Pocketlang
github.com
github.com
In my experience, Haskell's syntax is much simpler than the syntax of any of the popular languages. The "hard" parts of Haskell come with all the abstractions people make (esp. how it encodes side effects), the laziness, and the language extensions. Dhall has none of those.
To be very explicit, I'm dodging the question because it's ultimately subjective and people come out of the woodwork with the same predictable talking points ("syntax doesn't matter", "but it's VERY readable! look how few characters!") and I don't have the energy this morning.
Fair enough, but I've never seen anyone make either of the talking points that you claim are common, and they would be very silly things to say.
Count yourself lucky
> they would be very silly things to say
I tend to agree
I can imagine a curly-braced syntax for Dhall (BTW Haskell does have curly-braced syntax when you need it), curly-braced syntax for Python, etc. Indent-based syntax for HTML was implemented (but I forgot the name).
Also, RTL syntax and Arabic / Hebrew keywords for languages have also been implemented; this must be a huge help to those whose native writhing systems are RTL. Try writing your code right-indented and with all expressions backwards.
The python standard library is where I think the strength of this approach lies. Was reading some history on why reddit was rewritten in python (after initially implemented in LISP).
Transpiling python stdlib is a significant task in itself and could use more love.
My suggestion to the author is to think more on the selling points of the lang. is it the intention of this language is remain small and fast, or is it just a temporary property of the language because it is so new? Most languages start out as fast as C on toy problems, and then slow down as programs become larger as the language becomes more capable. Often it’s the case then you implement the cool features you want your language to have, it’s several orders of magnitude slower than when you started. That’s why so much time is spent on compiler optimizations.
I have this desire to create a (maybe domain-specific / not Turing) programming language. I have some use cases involving constraint satisfaction but basically it's a rock'n roll dream kind of thing for me.
I had to read this a few times to understand that this isn’t saying that Pocketlang is not written in Wren. I was looking for Wren code in the repo and I was slightly confused.
Very cool project though! I always love to see projects inspired by Crafting Interpreters.
I had to read that a few times to understand what I think is an unintentional double negative on your part.
The author used Wren as an example/reference on how to build a programming language, but built something unrelated to it.
Correct?
I shouldn’t be allowed on HN until I’ve had my morning coffee.
> Pocketlang is a small (~3000 semicolons) and fast functional language written in C
From what I can tell from the comments, pocketlang re-uses and/or re-implements some functionality from the wren language source code:
$ grep wren src/*.h src/*.c
src/pk_compiler.c: /* String interpolation (reference wren-lang)
src/pk_utils.h:// Source : https://github.com/wren-lang/wren/blob/main/src/vm/wren_utils.h#L119
src/pk_utils.h:// Copied from wren-lang.
src/pk_var.h: * wren (https://wren.io/) an awesome language written by Bob Nystrom the
src/pk_var.h: * https://github.com/wren-lang/wren/blob/main/src/vm/wren_value.h
src/pk_var.h:// usage and it has 2 formated characters (just like wren does).I don’t know why that is - maybe there just isn’t much of a niche for a lightweight JIT compiler.
What features make this a functional language?
When I was in school (1990s), simply having first-class procedures was good enough for most people to consider a language functional. I'd assume that's roughly the definition being used here.
But you go back to 20 years before that, and it wasn't totally unheard of to see higher-order functions in procedural languages (such as Algol 68) and object-oriented languages (such as Smalltalk). And you fast forward 20 years, and about the only language without some form of first-class procedures that's still allowed to exist seems to be C. And in the middle there's always been Python.
You could go all purist and say that, since John Backus coined the term, we should stick with his definition. In that case lisps are definitely out (he explicitly said so in his paper), and it's possible that the only genuine examples are Miranda, Haskell and friends, because even allowing mutation or an imperative style will disqualify you. But I'm not sure everyone really wants to snub Robin Milner like that.
It's almost like it's an ill-defined term with fuzzy boundaries that means whatever the person currently using it wants to tell you they meant by it, and trying to be pedantic about it is mostly just a good way to have a frustrating conversation. Kind of like just about every adjective that can be used to describe programming languages.
> func(x) return x*x end # Lambda/literal functions. [1]
[1] - https://thakeenathees.github.io/pocketlang/getting-started-l...
[Edit]: To answer myself the API seems really clean and neat, it looks like the patterns used to implement the standard modules can be used as is - e.g. to implement a third party native module, a good pattern to start from is to observe how _fileOpen is implemented in cli/modules.c and added to module using pkModuleAddFunction
The problem with this approach is that limiting the number of instructions doesn’t necessarily limit the amount of time taken. Any single VM instruction could be a call into a C function that performs a long-running computation.
If you want to robustly limit the amount of time a script runs for, you have to actually time it.
For instance when evaluating NPC AIs it may be important that an NPC isn't left dangling in a random state at the end of a frame, but either has finished evaluating, or hasn't started yet.
https://thakeenathees.github.io/pocketlang/language-api-fibe...
if x < sin(5) + cos(20) then y = 5;
If "x" and "sin(5)" was evaluated but not "cos(20)" then it should just remember VM state and continue next time. I did this in JS and it worked great for distributing NPC load between frames (https://twitter.com/dusan_halicky/status/1173924435923001344) and it didn't required any understanding of the code (I didn't need to carefully check when I need to stop execution), just VM snapshot and continue next frame.(Or at least I assume it works that way based on studying Wren.)
1. App https://apps.apple.com/de/app/j701/id1255235993?l=en (there’s an android version I believe)
2. Copy input from page
3. `+/ ".jgetcb''` to get sum
[fn x for x in ... if ...]
I know there's a `map` in, say, `multiprocessing.Pool`, but using that doesn't feel as natural as a comprehension in python or `map` in, say, Haskell or Kotlin.