POOL – Thoughts on its syntax

This article is an collection of my thoughts on the syntax of the POOL programming language. It may evolve and be updated (and written) over time. Furthermore it’s like a blue print for my later work on the parser and the grammar, therefore it’s written like a language reference. It’s my first article of this kind (and its using terms from Java, JavaScript and Ruby), but I hope it’s none the less readable and gives a good (and deep) overview of the language.

Notes on the formatting of this article

  • Uppercased words or words in brackets are placeholder.
  • CODE #-> VALUE means that the CODE returns (or emmits) VALUE
  • CODE #~> VALUE means that the CODE returns (or emmits) something equivalent to VALUE
  • , ... means that the pattern used before the comma is repeated

Syntax basis and philosophy

The syntax of the language is heavily based on the syntax of JavaScript (JavaScript is even to some extend valid pool code) and Ruby as JavaScript has an easy syntax and I like Ruby (it’s syntax is great and easy to understand). Therefore the syntax for simple comments, assignments, property access, method calls and primitive data types (I mean numbers, arrays, strings and booleans) is the same as in JavaScript (and Ruby) and so I assume that you understand this parts of the syntax when used here, I set it for now at side and cover them after core parts of the syntax later.

The philosophy of this syntax to emphasize that everything (yes, everthing) is an object and to allow as much flexibility as possible.

Objects

Objects are the base of the language, so their syntax one is really simple (an bourroughed from JavaScript):
obj = {"KEY": [value or expression], ...}, if KEY is a valid variable name or not a string obj = {KEY: [value or expression], ...} or an empty object empty_object = {}.
Elements of the object can be accessed either with obj["KEY"] or if KEY is a valid variable name obj.KEY. Not existing properties have the value nil, if a not existing method is called on this object, it’s undefined_method function is called (as you may have recognized, I use the term method and the term function mostly as synonyms). Inside the object, you can directly access its properties with just KEY if KEY is a valid variable name (but later more on this topic).

Every object has some properties and methods built in (which can be overriden, but be really careful), some of them have aliases for convenience:

$size
the number of key value pairs in the object minus the built in ones (and the ones beginning with $.
function $contains(KEY)
checks whether the object contains the KEY
function $delete(KEY)
deletes the KEY value pair
this or $this
the current object
$parent
the object this object is a part of – the parent object.
@KEY is a short cut for $parent.KEY
$module
the module this object is part of ($module and $parent could possibly be the same)
$type or $class
type of the object:
obj.$type == "Object": the object is a simple objectobj.$type == "Module": the object is a moduleobj.$type == "Function": the object is a functionelse the class name of object, alias for $class.name
$class
Class object this object is an instantiation of.
Normal object: Object, …
Class object: Object
function undefined_method([method name], [parameter object])
This method is called whenever a not existing method is called on this object (e.g. obj.not_existing_method(34)). The default implementation throws an exception.
$private
An object containing the private properties of this object.
$protected
An object containing the private properties of this object which are also accesible from subclasses (is only important in class definitions)
$module_private
An object containing the properties accesible from within the same module.
The object inherits some more built in methods and properties which will be described in a detailed object reference.

Modules

Modules are simply objects with a different syntax, the ability to import functions and objects of another module in to it via the built in import([module reference or module name]) function (if there is no such module, the interpreter searches and requires the appropiate file if their is one, if not throws an error). The code inside a module is excecuted when it’s loaded or required (via function require("FILE_NAME"), if FILE_NAME has no file ending, the function adds .pool). Modules can be nested in side one another, but not into objects.

Their syntax is easy:

module MODULE_NAME {

[CODE]
}


or in a more literal and Ruby like style:

module MODULE_NAME
[CODE]
end

Example:

module Test.Module //Every valid reference is alowed. Just Test has to be a module (it will be created if is doesn't exist)
import(IO) //IO is a built in module
obj = {"3": 3} //creates an object, that can be accessed from the outside via Test.Module.obj
end

Every code outside a module (and modules outside of other modules) are placed into the STDModule.
As Modules are (after they’re loaded) some kind of objects they inherit the built in functions and properties of them.

Functions

Define a function:

function [variable name]([parameter list]){
[CODE]
}

Define a closure:

[variable name] = function([parameter list]){
[CODE]
}

Or in a shorter way

[variable name] = {|[parameter list]|
[CODE]
}

or (of course)

[variable name] = do |[parameter list]|
[Code]
end

|| can be omited if the closure has no parameters.

Closure and functions are over all the same, in fact the only difference between the two is, that functions allow back referencing (the interpreter recognizes them during parsing). Therefore function can be used as closures and so everything I say about functions will (if I say nothing explicit) also apply to closures.
The parameter list: [parameter (a normal variable name, the given value is assigned to)], [another parameter], ...

Or if you want to set a default value for one parameter:
[parameter]: [default value], ...
If you use an expression instead of an explicit value, the value will be evaluated every time the default value is used. But if you put a ~ in front of the colon (~:) the value will only be evaluated once and then cached (so don’t use $caller there). It’s also important, that the scope of such an expression is the function scope (you’re able to use $caller, $this, …).
If you want to auto clone the given value of a parameter (I know, it’s the other way aorund in PHP but hopefully it’s not to hard to memoize the difference) you can prefix PARAMETER with an ampersand (&PARAMETER).
You’re able to preset a return value for a given set of parameters of a function:

FUNCTION(3) = 4

Built in variables of of the function object:

this or $this
the current function object
$this.$caller or simply $caller
the caller function object
$local
the local variables
$param
the current parameter object, $param = {[first parameter name]: [value], ..., $other = []}.
If a parameter isn’t given, it’s value is nil, if a parameter is given without a corresponding parameter name, it’s added to the $other array
Please don’t use constructs like the caller of the parent object, as it’s value is going to be nil and therefore is useless.
$default
the parameter default values, $default = {[first parameter with default value]: [default value], ...}
$ast:
it will probably be added later and will allow the modification of the Abstract Syntax Tree of the function body.
$yield
Closure the function is called with. Short for $param.$yield

Instead you only using the keywords function or def you’re also able to create special function types by pefixing these words, [prefix]function or [prefix]function (they can also be combined). Special types and their prefixes are the following:

sef_
sef stands for „side effect free“. This function type caches the results in $cache = {[parameter object]: [function result], ...} (could be changed in the future)
pdf_
pdf stands for „preset default value“. It’s a function type that returns the same function with the given parameters preset (their default values, to be correct), if other parameters (with no default values) aren’t set.

They’re simply short cuts for setting the value of the property $is_pdf or $is_sef to true accordingly.
Example:

pdf_function pow(base, exponent) { base ** exponent }
pow_two = pow(exponent: 2) #-> {|base, exponent: 2| base ** exponent}
pow_two(3) #-> 9

Return values

Values are returned explicit via return VALUE or implicit (the value of the last expression is returned).

Call a function

You call a function as you would expect via FUNCTION([first parameter], [second], ...). You’re able to replace [first parameter] with [parameter name]: [parameter value] to set the value of a special parameter out of the normal order (e.g. FUNCTION([first parameter], [parameter name]: [value], [second parameter])). To pass a nil value for a parameter, you can either type nil directly, or omit the value (e.g. FUNCTION([first parameter],, [third parameter]), FUNCTION([first parameter], [parameter name]:, [third parameter])). A nil value is replaced by the default value of the parameter (if there’s one).
You can optionally pass an code block stored in the $yield variable in the function:

FUNCTION(PARAMETERS) CLOSURE
arr.search() {|a, b| a > b }

Variable names
Valid variable (and function and module) names consist of an alphabetical or _ character or a dollar sign optionally followed by alpha numerical or _ characters and optionally ended by a ? or ! character (or as an regular expression /$?[a-zA-Z][a-zA-Z0-9_][!?]?/).
Variable names are case sensitive and only allow ASCII characters (no UFT8).
The following are some naming conventions (partly coming from Ruby, JavaScript and Java and not enforced by the interpreter):
– functions returning booleans end with a ?
– only functions that modify the object, they’re called on, and with a !
– built in functions and properties of objects, functions, etc. start with a $, some have aliases for convenience that aren’t (e.g. $this has the alias this).
– class and module names are camel cased, the other variable names not (using _ instead)

Comments
As I said at the beginning of this article, you’re able to write comments as you’re used to in JavaScript or Ruby, both syntaxes are supported:
One line comment:
//COMMENT TEXT or #COMMENT TEXT
Multi line comment:

/*
MULTILINE
COMMENT
*/

or

MULTILINE

COMMENT

Documentating of modules, classes and functions
Documentation consists of multi line comments in front of and is modeled after JavaDoc.
Structure of the comment text:

SHORT DESCRIPTION

OPTIONAL DETAILED DESCRIPTION

OPTIONAL INFORMATION

(the second free line is optional)
Optional information tags (have to be in different lines):
@version VERSION:
version of the class or etc.
@license LICENCE
License the code is licensed under.
@author AUTHOR
Author of the code
Function specific tags:
@param PARAMETER_NAME TYPE DESCRIPTION
information for the parameter PARAMETER_NAME, if you want to write more than one type, just seperate the types by | characters (e.g. TYPE1|TYPE2.
- @returns TYPE description
information about the return type of the function

Variable assignment
= (in object definitions : is used instead but it works similar) without a prefix is asimple assignment by reference. The allowed prefixes are the following:
~: lazy assignment
the expression at the right side is evaluated the first time the value of variable is really used
&: assignment by value
assigns the cloned value of the right side expression to variable
:: final assignment. (set is_final of the variable object to true)
- ?: sets the value of the variable if it's current value is nil or null, can't be used to assign a value to a set of parameters of a function.
Assignements can be cascaded via commas: [assignment], [assignment]

Variables
:VAR : variable object containing the value of VAR
properties:
set : called when the value of the variable is set
get : called when the variable is accessed
is_final : true if constant
value : value of the variable

Class
class CLASS {new:: function(){}, super: class obj, static: {}, possible: array_get [i], push [<<], pop [>>], add [+], sub [-], mul[*], div [/], mod [%], pow [**]}
for usability reasons some of the magic is performed by the interpreter indirectly, to allow a simpler method definition. I can’t write much about that, as it depends strongly on the implementation. New objects are created via CLASS.new(PARAMTER)

TODO write more text…

Built in types

Built in types are types with a native syntax, like Strings or Numbers
(but without modules, classes, object and functions in this context). The following lists them with their native syntax and a short description.

Float
Syntax to create an floating point number 10: 10.0 or 10f or 1.0E1 or 1fE1 (the number behind E is the exponent x in zEx = (10 ** x) * z) or (of course) Float.new(10)
Integer
The syntax is equivalent to the Float syntax: 10 or 1E1 or Integer.new(10).
If an Integer is used in a expression with a float it will be used as a float. In general float values are rounded to smaller integer if they are converted to an integer.
String
Strings are created via "[characters, can span across lines]" or '[characters]'.
You can insert code into the string (it’s result will be actually inserted) via #{[CODE]} into " Strings (backslash expression like \n are also only converted in this type of String
This code will be treated as a closure: "TEXT #{[CODE]} TEXT"
is equivalent to "TEXT" + {[CODE]}() + "TEXT"
Literal
Essentially Strings consisting of one character, no new class but used in the following as a term.
Boolean
true or TrueClass.new(), false or FalseClass.new().
More information in the section about boolean expressions.
Nil
nil or NilClass.new() acts like false in boolean expressions.
Is the value of an unknown variable or of a function or expression returning no value.
Null
null or NullClass.new() acts like false in boolean expressions.
Is the value of known but unset variables. May be removed later.
Range
BEGIN..END or Range.new(BEGIN, END), BEGIN...END
or Range.new(BEGIN, END, false). Range objects created using ..
run from the beginning to the end inclusively. Those created using ...
exclude the end value. BEGIN and END can be of type Integer, Float or Literal.
RegExp
/[Regular expression]/ or RegExp.new('[Regular expression]').
Is a regular expressions, strings can be matched against.
The actuall regexp syntax is determined during implementation.

Boolean expression


Every value except null, nil and false evaluates to false all other values evaluate to true. There are different types of modifiers in boolean expressions, listed below in their precendence.

EXPR or (EXPR)
The value of the expression, which could also be a single value
!EXPR or not EXPR
Negates the following boolean
EXPR && EXPR or EXPR and EXPR
Logical and.
EXPR || EXPR or EXPR or EXPR
Logical or.
EXPR xor EXPR
Exclusive or.
EXPR == EXPR or (EXPR).equals(EXPR)
True if both values are the same (no automatic casting, therefore no === is needed)
EXPR =~ EXPR
Used when only if one of the to values is an regular expression, the other value is tested against, or if the first value is a range and the second value is included in the range

Control constructs

EXPR is a boolean expression. Variables defined in the code blocks are only visible in this code block, but variables of the sourrounding (module, class, object, function) scope can be accessed without any prefix.
An important information is that such constructs return the value of the last expression of their code and that you can break out such a construct via break (use break DEPT if you want jump out of the DEPTth parent construct), returns the value of the expression before the break.

Conditions

There are several ways to define a simple condition:

if (EXPR){
[CODE]
}

or with only a single of code:

if (EXPR) [single line of code]

or (maybe not implemented)

[single line of code] if (EXPR)

More advanced conditions with if and else:

if (EXPR){
[CODE]
} else {
[CODE]
}

or with only a single of code:

if (EXPR) [single line of code]
else (EXPR) [single line of code]

the same with several conditions:

if (EXPR){
[CODE]
} else if (EXPR) {
[CODE]
} else {
[CODE]
}

You can replace if with unless if you want to execute the code block when the boolean expression is false.
The ternary version is also allowed (as you know it): EXPR ? CODE : CODE .

Switch-case


Switch case statements in POOL are similar to them of other languages like JavaScript, so I'm only going do cover the differences.

switch ([Value or variable, VAL]){
case [EXPR]:
[CODE]
break;
case [EXPR]: [CODE]; break
case~ [EXPR]:
[CODE executed if EXPR =~ VAL is true]
break
case+ [EXPR]:
[CODE executed if EXPR is true]
break
else:
[CODE executed if no other case-condition matches]
}

If switch is replaced with switch+ breaks will be auto inserted after each case statement.

Loops

As you know and love them.

For loop


for ([assign a variable or not]; [condition tested after each loop cycle, or not (then you've got and endless loop)]; [statement executed after every loop cycle]){

[Code]
}

While loop


while(EXPR) {
[CODE]
}

or if you want execute code while the expression is false:

until(EXPR) {
[CODE]
}

Begin-while loop


begin {
[CODE]
} while (EXPR)

or if you want execute code while the expression is false:

begin {
[CODE]
} unless (EXPR)

Infinite loop


loop {
[CODE]
}

Exceptions

The specific exception classes are defined during the implementation. All exception classes extends the class Exception.

Exception throwing


throw [exception class].new([parameters])

Please add a @throws tag to the appropriate comment.

Exception handling

Exceptions are handled with a Java like syntax:

try {
[unsafe code]
} catch ([Exception class, if you catch more than one, seperate them with a vertical bar] [variable the thrown exception is assigned to]) {
[CODE]
}

You can optionally add a finally { [CODE] } after the catch statement, CODE will than be certainly executed and you can add serveral catch statements after the first.

Veröffentlicht unter POOL

Sie spielte sich durch ihr Leben

Zitat

Ziellos herrumirrend musizierte sie sich ihren Weg durchs Leben.
Spielte Dur und auch manchmal Moll Akkorde.
Sie spielte und spielte sich durch die Welt.
Sie spielte nur für sich.

– Sie spielte sich durch ihr Leben, Ich im letzten Jahr

Mein Kater bei Sonne

Galerie

Diese Galerie enthält 4 Fotos.

Zwei Bilder meines Katers Anton, wie er sich entspannt bzw. in die Kamera stupst und sich über das schöne Wetter freut. In seinen Augen spiegele ich mit meiner Kamera wieder. Die Schnappschüsse sind heute Nachmittag auf dem Balkon entstanden.

An Goethe – Friedrich Nietzsche

Das Unvergängliche
Ist nur dein Gleichniss!
Gott der Verfängliche
Ist Dichter-Erschleichnis…

Welt-Rad, das rollende,
Streift Ziel auf Ziel:
Not — nennt’s der Grollende,
Der Narr nennt’s Spiel…

Welt-Spiel, das herrische,
Mischt Sein und Schein:
Das Ewig-Närrische
Mischt uns hinein!…

[Ein wunderschönes Gedicht zum Abschied von geliebten Personen.]

POOL – Fibonnaci sequence

I’m going to post some example code snippets, like the following, written in POOL to demonstrate some of POOLs cool features and to have some test code when I’m writing the parser and the interpreter.

This code snippet eveluates the fibonacci sequence recursively, using the memoizing features of the special function type sef_function to avoid on the usual drawbacks of recursive evaluation: the multiple calculation of the same value.


sef_function fibonacci(n){
fibonacci(n - 1) + fibonacci(n - 2)
}
fibonacci(0) = 0
fibonnaci(1) = 1


fibonacci(5) #-> 5
/* Call stack of fibonacci(5):
fibonacci(5)
-> fibonacci(4) + fibonacci(3)
-> (fibonacci(3) + fibonacci(2)) + fibonacci(3)
-> ((fibonacci(2) + fibonacci(1)) + fibonacci(2)) + fibonacci(3)
-> (((fibonacci(1) + fibonacci(0)) + fibonacci(1)) + fibonacci(2)) + fibonacci(3)
-> (((1 + 0) + 1) + fibonacci(2)) + fibonacci(3)
-> ((1 + 1) + 1) + fibonacci(3)
-> (2 + 1) + 2
-> 3 + 2
-> 5 */

Abschiedsworte an Pellka – Joachim Ringelnatz

Jetzt schlägt deine schlimmste Stunde,
Du Ungleichrunde,
Du Ausgekochte, du Zeitgeschälte,
Du Vielgequälte,
Du Gipfel meines Entzückens.

Jetzt kommt der Moment des Zerdrückens
Mit der Gabel! – Sei stark!
Ich will auch Butter und Salz und Quark
Oder Kümmel, auch Leberwurst in dich stampfen.
Mußt nicht so ängstlich dampfen.

Ich möchte dich doch noch einmal erfreun.
Soll ich Schnittlauch über dich streun?
Oder ist dir nach Hering zumut?

Du bist ein so rührend junges Blut. –
Deshalb schmeckst du besonders gut.

Wenn das auch egoistisch klingt,
So tröste dich damit, du wundervolle
Pellka, daß du eine Edelknolle
Warst, und daß dich ein Kenner verschlingt.

Warmer Regen

Unverkrampft stand er da im Regen. Es prasselte auf ihn in dicken Tropfen hernieder. Doch es war nicht unangenehm, er stand auf einer schönen, grünen Wiese und der Regen war warm. Die Luft duftete nach Wiesenkräuter, deren Düfte durch die nasse Luft aufgesogen wurde. Ein schöne Landschaft. Und so stand er da noch immer. Vernässt aber glücklich und mit der Welt zu frieden. Das war sein Traum, der da Wirklichkeit wurde. Er wusste nicht wie er hergekommen war an diesen unscheinbaren Ort in mitten eines großen Waldes. Er kann sich an nichts mehr erinnern, was zuvor jemals geschehen war. An keine wichtigen Ereignisse in seinem Leben, nicht was er beruflich tat und nicht was ihn dazu gebracht hatte hier zu stehen. Aber das war nicht wichtig, denn er war glücklich. Glücklich in der Abgeschiedenheit von allem bösen in der Welt, von allen Problemen, von allen Ängsten, einfach von allem das ihm auch nur im geringsten die Laune verderben könnte. Der Regen hatte nicht aufgehört und rieselte in warmen Wogen aus dem Himmel ihm entgegen. Seine Kleidung war nun total durchgenässt, doch das machte ihm nichts, denn er fühlte sich eins mit der Natur. Und wünschte sich, das die Zeit an diesem Ort nie Enden würde. Das tat sie auch nicht, denn es war sein Traum…

Meine aktuellen Projekte – ein kurzer Überblick

Zur Zeit habe ich am ein paar Projekte am laufen und in Planung, die ich in diesem Artikel kurz beschreiben möchte.

Die Projekte sind folgende:

Studium
Verständlicherweise mein wichtigstes Projekt, wenn man es überhaupt so nennen kann, welches in gewisserweise allen anderen Projekte beeinflusst, zeitlich wie auch ideel, und in nächster Zeit auf Bereiche der Mathematik konzentrieren wird.
POOL
Eine einfache, strikt objektorientierte, dynamisch typisierte Programmiersprache. Sie bildet mein „großes“ Projekt im Bereich der Informatik für die nächste Zeit. Zur Zeit bin ich gerade an der Fertigstellung der (vorläufigen) Grammatik und Sprachspezifikation, die ich dann in nächster Zeit hier im Blog veröffentliche. In nächster Zeit wird die die Hauptarbeit wohl in der Implementierung der Grammatik liegen.
Zeitgenössisches Karlsruhe
Photographische Momentaufnahmen aus Karlsruhe – die ich hier (wie auch die Idee dahinter) veröffentlichen werde. Weiterlesen

Kurzgedanke

Seichte Unterhaltung wollte er. Seichte Unterhaltung als Balsam auf seiner Seele in dieser aufregend melancholischen Zeiten. Doch daraus wurde nichts. Er hatte sich einen Klotz ans Bein gebunden und dieser Klotz verlangt gerade wieder seine volle Aufmerksam. „Seichte Unterhaltung“, dachte sich wohl der Klotz, „kann ich dir geben“, und zog mich noch tiefer in meine Melancholie.

POOL – an object oriented programming Language

I’ve a dream to build an object oriented language. Last year, I built an tiny modeling language for Mealy and Moore automatons. It felt great to develop my own little grammar with ANTLR and seeing it working. You can find this project (AutomatonLang) in my github repository. Now as I’m beginning to study computer science, I thought about a new project (after I finished my work for the abipage project) to work on in my spare time, a project that has more to do with my field of study then building little websites, etc. And so some thoughts popped up in my mind. One of it was to realise on of my dreams – to build an programming language. It sounds annoying for most of my contemporaries, but for me it felt just just great thinking about designing and developing a new programming language with grammars, parsers, documentation and everything. It’s now my main spare time project for as long as it takes, I assume several months or more, and I hope it’ll be as much fun as I’m expecting it to be and that I’m learning all sorts of skills (I’m optimistic). I’m going to write, in this and in following blog posts, about thoughts and ideas on programming languages and my attempt to build one on my own. I hope they are helpful to you if you’re planning the same type project. Up to this day I’ve only ideas about the design in my mind and haven’t written any line of code or grammar – this post is about my ideas and the general decisions I’ve made.

Weiterlesen

Schöne Wandzeichnung

Bild

Skizzenhaftes Portät eines Unbekannten an einer Karlsruher Hauswand

Skizzenhaftes Portät eines Unbekannten an einer Karlsruher Hauswand

Diese Wandzeichnung, ich gabelte sie erst kürzlich auf, macht auf mich den Eindruck, als wolle sie mir etwas sagen. Aber aus Ermangelung anderer Ausdrucksmittel schaut sie mich nur ide ganze verschmitzt an. Als wolle sie mir etwas sagen. Also wolle sie mir sagen, wie schön mein Leben doch sei. Wie schön es doch sein muss frei herumlaufen zu können anstatt hier an einer Wand festgemalt zu sein. Doch wie viel weiß die Zeichung, skizzenhaftes Abbild eines Menschen, denn schon von der Welt? Sie ist immer nur am gleichen Ort und kann den eigenen Erfahrungsschatz nur daraus bilden, was es in seinem Blickfeld sieht – was nicht wirklich viel ist, dass es auf eine Mauer einer Garageneinfahrt gemalt wurde. Doch kann es sein, das sie trotz dessen einen Weisen Blick auf die Welt geworfen hat und zu geistreichen Schlüssen gekommen ist, zu denen nie eine lebende Kreatur fähig wäre. Vielleicht verstehe ich die Wandzeichnung einfach nicht richtig. Vielleicht versteht sie mich nicht. Vielleicht. Vielleicht hat einfach der Schöpfer dieses Kunstwerks genau das im Sinn gehabt: Das man vor ihm steht und sich Gedanken macht.

Häkeln

Bild

Ein selbst gehäkeltes Mäppchen aus roter Wolle.

Ein selbst gehäkeltes Mäppchen aus roter Wolle.

Seit gefühlten Jahren – besser gesagt, seit Anfang meines Studiums – sammelten sich immer mehr Bleistifte an, doch ein passendes Mäppchen für sie habe ich noch nicht gefunden. Doch warte dachte ich vor ein paar Tagen, habe ich nicht irgendwann einmal häkeln gelernt? Ich hatte in der Grundschule Handarbeitsunterricht und dürfte deswegen noch etwas Häkeln können. Also habe ich schnell eine Häkelnadel und Wolle gekauft, einen Arbeit Crashkurs Häkeln und fertig war mein erstes Häkelstück seit langem – ein schön rotes Mäppchen…