YaK:: TerseTalk (Terse Talk) [Changes]   [Calendar]   [Search]   [Index]   [PhotoTags]   

TerseTalk (Terse Talk)

TerseTalk is a re-invention of a simplified Smalltalk, written in Java, for various reasons.

FUTURE SITE -> http://tersetalk.yak.net/

GITHUB -> https://github.com/strickyak/TerseTalk-Alpha

Work In Progress: http://yak.net/repos/terse/ (use darcs if you have it)

It's unfortunately not ready yet for Alpha. Contact <strick> for more info.

Pre-alpha releases (safe to try): http://yak.net/repos/tmp/A41.apk (also look in that directory for more recent versions).

Archaic Grammar -- No Longer Accurate

Primatives are Literals, variable names, reserved names, macros, expression lists in '(' ')' parentheses, and the unit (empty) vector '()'.

Literals are Num, Str, and Blk values.

Num are floating point Java doubles.

Str are java Unicode Strings with 16-bit chars. As in smalltalk, Str literals are written with single quotes. To escape a single quote, double it. There are no other escapes.

Blk is like a smalltalk Block, representing zero or more parameter variables, and a list of zero or more unevaluated expressions (see ExpressionList below). Alone, it evaluates to itself (like other literals).

Syntax: [ :var1 :var2 . expr1 . expr 2. expr 3. ]

Variable names may be instance variables, local variables, or global class names (you cannot assign these globals, and they are only classes, unlike smalltalk). A variable is instance if it's defined such in the class. It's local if it's assigned or a block parameter. Otherwise it's global (unless it's reserved). Case doesn't matter (obj and Obj and OBJ are all the same).

Reserved Names are se, self, su, super, and nil. The short forms se & su are abbrevs for self & super.

Unary messages are an identifier following a primative, as in smalltalk. (They may also follow "--"; see below.)

Grammar: unaryExpr ::= primative ( unaryMessageName )*

Binary messages.

We don't have binary messages (yet). Use the following keyword messages instead:

+ - * ---> pl: mi: ti:

== != < <= > >= ---> eq: ne: lt: le: gt: ge:

Keyword messages

As in Smalltalk, they follow the receiver, with a keyword and a colon before each argument.

You may use '/' instead of ':' if it's easier to type.

Example: a at: b put: c sends the message "at:put:" to receiver a, with parameters b and c. It can also be written a at/ b put/ c

Grammar: keywordExpr ::= unaryExpr ( keywordMessagePortion )*

keywordMessagePortion ::= keyword (":"|"/") unaryExpr

Extra Keyword Feature: You can use more than one ":" or "/" to indicate binding levels. Example:

a at/// x ti/ x pl// y ti/ y put/// 1

To read it, first look for one /, and you find exprs "x ti/ x" and "y ti/ y". Then look for two //, and you find the pl// operation on those 1-/ exprs. Finally look at the /// keywords, and you find the message "at///put///" which is the same as smalltalk message "at:put:". The number of '/' or ':' does not change the message; it just shows what binds first. So that expression is equivalent to normal smalltalk

a at: ((x ti: x) pl: (y ti: y)) put: 1

Dash Expressions

Another grouping mechanism is the double dash "--". It finishes the keywordExpr before it, as if you put parens around what's before it, and it must be followed by a unary or keyword message, which is sent to the result of what was before the double dash.

Example: Dict new at: 'x' put: 10 -- at: 'y' put: 20.

is the same as

(Dict new at: 'x' put: 10) at: 'y' put: 20.

Note: We do not have the "cascade" (using ";") of normal smalltalk. Instead we have double dash. They are different.

Grammar: dashExpr ::= keywordExpr ( "--" ( unaryMessage )* (keywordMessagePortion)* )*

Comma Expressions

Commas create tuples (like in many languages such as Python) of 2 or more dashExprs. Multiple commas work together to create longer tuples. Our tuples are not a distinct tuple type; they are just Vecs.

Example: a at: 'x' -- sin , a at: 'y' -- cos, a at: 'z' creates a 3 element Vec, just like this does: Vec[ (a at: 'x') sin. (a at: 'y') cos. a at: 'z'. ]

Grammar: commaExpr ::= dashExpr ( "," dashExpr )*

Assignment Expressions

Assignment to instance or local variables is done with the "=" operator, or if it's easier to type, you can use "@" instead. If the value being assigned is a Vec, you can use "destructuring" assigment to several variable names separated by ","s.


z = x ti: y

a, b, c = c, b, a

Grammar: assignExpr ::= ( varname ( "," varname )* ("="|"@") )? commaExpr


Multiple commaExpr may be joined with "." (as in Smalltalk) to create an ExpressionList. Usually the result of evaluating an ExpressionList is the value of the last commaExpr, after evaluating them all left to right.

However in some circumstances inside a Blk, depending on what message is sent to the Blk, they are evaluated differently.

Method Definition

The body of a method is an ExpressionList, which evaluates to the value of the last expr in the list.

There is no return operator "^" as in smalltalk.

Local Scope

Each method invocation (where the method is defined in TerseTalk, as opposed to those builtin) gets its own local scope. If the method is called recursively, each recursion gets its own scope, as you would expect.

However there are no lexical scopes within that local scope. In particular, parameters to Blocks do not have their own scope.

If you really need more scopes, split it into more methods.


Comments are in double quotes.


A primative expression composed of an identifier and a block, possibly repeated.

macro ::= ( macroName "[" paramList exprList "]" )+

This is a hack to make TerseTalk a little more readable to non-Smalltalkers by being a little more prefix- instead of suffix- oriented, especially for long data definitions Vec[] and Dict[], and for things that would be "statements" in other languages, like If[]Then[]Else[] and For[]Do[].

They are used for specific idioms. Usually each expr in the exprList is evaluated separately for its own value, rather than the normal rule in a Blk, where the value is the value of the last element.

Vec[ a. b. c. ]
defines a vec with the 3 members a, b, and c.

Dict[ 'x', 10. 'y', 20. 'z', 100. ]
defines a Dict with keys 'x' 'y' and 'z', and the given values. (Notice the comma expressions build association tuples.)

If[ a. ]Then[ b. ]Else[ c. ].

For[ list. ]Do[ :i. sum = sum pl: i. ].

While[ cond. ]Do[ statements. ].

err = Catch[ something might: fail ].

Typing Shortcuts

One reason TerseTalk is so Terse, is to make it more usable on tablets or phones. The following char substitutions may be useful on limited keyboards:

: <--- /

= <--- @

[ <--- !

] <--- ?

( ... ) <--- r[ ... ] <--- r! ... ?

Thus TerseTalk should be usable with only these punctuation characters (which happen to be easily available on the default Android English tablet keyboard):

, . - / @ ! ?


d = (t = DemoLissajous meths at: 'step' $top ) sends.
m = FOR(k:v: d) MAP(
  ('key',k,'val',v) join: '~'; FOR(i: v) MAP(
   IF(i >= 0) THEN(
          r = Rex new: '[A-Za-z0-9_]+:?'.
          r match: (t source substr: i to: (t source len))
    ) ELSE('---')
m .

(unless otherwise marked) Copyright 2002-2014 YakPeople. All rights reserved.
(last modified 2012-05-26)       [Login]
This page is referenced by the following pages: