# Lyn Old swedish for lönn. Pardon my ramblings, this is an initial document to collect my thoughts about what I might want from this project. ## Concept Tcl is cool, but no quite enough like Lisp, right? This is my toy embeddable scripting language, takes heavy cues from Tcl but goes more in the Lisp direction by not requring `$` in front of everything and having a type system (though more inspired by ML with implicit type inference. Though the type inference thing might be implemented a bit later due to it possibly being a bit too heavy for a simple scripting language, but we'll see. This does mean that the language is **not** suited quite as well for user interfacing stuff as Tcl (shells, prompts, etc) but might work decently well as an alternative to Lua (games, extensible editors, etc). I don't think people who enjoy Lisp will like this language as I'm going for a lot more imperative features, like in Tcl. In an ideal world, I think we would have three languages: 1. A compiled language for doing the heavy lifting of a program 2. A light scripting language for exposing functionality within a program 3. A (light?) shell language for user interfacing Tcl tries to do 2 and 3, and I personally think it achieves 3 very well. It's all about strings, which makes it easy and fast to use as a user interface, but this means that as a scripting language there's quite a bit of extra linenoise with `$` and some amount of mental overhead of keeping track of what a given string really tries to represent (is it an ad-hoc type? A class? Is it just a number?) This makes Tcl more difficult to deal with when the scripts grow in size beyond some (fairly small?) limit. You could of course argue that Tcl wasn't meant to be used to write these huge programs in and it's the programmers fault, but it will happen and I think a scripting language should still try to make that case as painless as possible. Speed probably shouldn't be the be-all end-all factor when designing a scripting language, but Tcl was for a very long time considered a *slow* language, which didn't earn it any favors. Even Python has an on-going performance improvement project, so I think speed should at least be considered when designing the language. ## Syntax As in Tcl, everything is just a bunch of commands. ``` cmd [arg1 [arg2 [arg3 [...]]]] ``` Sort of similarly to Tcl, curly brackets, `{}`, are used for grouping together commands but not executing them right away. Parentheses, `()`, group together commands and evaluate them immediately, producing a value. But here we already run into some differences between lyn and Tcl: + Values can be of different types, `int`, `double`, `string`, etc. + Procedures can **only** take values. Command groupings can only be passed to special `syntax` 'macros'. Here's an example (still up for change but let's go with this for now): ``` syntax for {init cond post body} { eval init while (eval cond) { eval body eval post } } def sum {n} { require n int let s 0 for {let i 0} {< i n} {set i (+ i 1)} { set s (+ s i) } return s } ``` They look kind of similar, but note that `for` is a `syntax` 'macro'. Effectively, macros can only take command groupings and create a new grouping that then later gets executed. Note that the groupings passed to `for` contain `()`, which are executed multiple times. (`syntax` 'macros' can also be defined in C, and presumably a lot of the looping constructs will be defined that way for a start) The `let` command defines a new variable, `set` mutates it. ## Some implementation ideas I'm currently considering letting the C api define variadic functions, but disallowing them from the scripting language (to start with, at least). The thing is that the C api can fairly easily define a type checking function that runs over the arguments as a list once we know how many arguments there are, whereas that is a lot more difficult to do in the script itself. Maybe a kind of ugly imbalance? `syntax` is visually just a procedure, but encountering one in the code probably requires a bit of extra handling. I'll have to dig into the exact details, but a syntax macro takes the command groups as they are and then can evaluate them multiple times in the containing context. Eventually I might like to implement this thing on top of my `ejit` engine, still unsure about some details but presumably this would mean that the most common functions should be 'pattern matched' and some equivalent bytecode be emitted, like `for/while/if` and mathematical operations etc. with slow paths as backups, I suppose? The main issue here is how `syntax` should be handled, if each `proc` is equivalent to one bytecode function should each `syntax` be inlined? How complex would that be?