

Show HN: Self-hosted stack-based programming language - Drahflow
https://github.com/Drahflow/Elymas

======
AlexDanger
I'm always impressed with people who invent things like this. Well done. It
inspires me to push my own skills, particularly when things get complacent at
work.

------
jdmichal
I find the differing syntax between function and variable storage to be
interesting. Is there any particular reason these aren't unified? Assuming
anything in brackets is a first-class "function" object, something like this
should be possible:

    
    
        2 /two define
        { two add } /addTwo define

~~~
Drahflow
The storage is exactly the same, the difference is only in what will happen if
the name is encountered somewhere.

{ 2 } /putTwoOnStack deff

{ 2 } /putClosureOnStack defv

putTwoOnStack dump # 2

putClosureOnStack dump # <function 0006002514AE5>

putClosureOnStack * dump # 2

~~~
couchand
I'm not convinced the distinction is valuable. Since you already have * and {}
you don't really need two distinct variable types.

~~~
Drahflow
I think it's a good thing (tm) that { x sin } could be valid code with x
pushing the value of x whereas sin is executing the value of sin.

Theoretically speaking, I need at least the deff and defq distinction,
otherwise { } could not be invoked during "parse" time. The defv case could in
principle be removed, but as * needs to execute (otherwise nothing ever will),
execution would need to be the default or I would need to decide based on
dynamic type. The first option would mean a lot of superfluous {} (or |
actually) around normal data variables, the second one would destroy the nice
similarities between arrays, strings and functions with integer domains.

------
Drahflow
The README claims easy Domain-specific-language creation. Here is a concrete
example how code which utilizes these features looks like:
[https://gist.github.com/Drahflow/c463717d5c72e114ac63](https://gist.github.com/Drahflow/c463717d5c72e114ac63)

~~~
Retra
For the love of brackets...

~~~
silon3
I miss semicolons ;)

~~~
Drahflow
There are semicolons :) They do sequential function composition:

{ /foo dump } /f defv { /bar dump } /g defv

f g ; /h deff

h # "foo" "bar"

------
r4pha
I also started toying around with a stack-based language [0]. It's
surprisingly fun!

[0] [https://github.com/rbaron/stacky](https://github.com/rbaron/stacky)

------
jerf
"Just because I'm not following the true path, doesn't mean I can't get it to
work."

I have to ask: Is that basically self-targeted snark about how you're not
doing this with Lisp?

I hope so, because I got a good belly laugh out of that interpretation.

~~~
Drahflow
It is self targeted snark allright. Not just not doing it with LISP, but also
ignoring pretty much everything I learned about compiler building in
university.

~~~
codinganarchy
I may only be a few years out of university, but over the last couple years
I've learned that what I studied in university falls into three categories:

1) Incredibly out of date.

2) Far newer than what my job requires me to use.

3) Existing in some ideal world that matches nothing anyone actually created
or uses in industry.

And yes, it's possible (and not rare at all) for both (1) AND (2) to be true
at the same time.

~~~
ucho
All of above - at the same time - ends up in the middle of Gartner's hype
cycles: a solution has been found 20 years ago and people are searching for
problem it solves ever since.

------
CamTin
This is great, and I'll definitely be playing with this tomorrow.

I also can't seem to stop myself going off half-cocked and writing language
interpreters[1][2] and virtual machines[3]. It's really quite addictive, and
gives you a "I really made something" feeling that a new backup script or CRUD
app doesn't quite provide.

I too actually started off writing a stack/RPN-style language for the exact
reason that I didn't want to do a proper parser, but then realized that, for
properly recursive structures like in Joy[4], it really makes it easier to
just write a parser. And it turns out that a recursive descent parser really
isn't that difficult, conceptually, once you spend the brain-time to work one
out yourself[5]. Like most things programmatic, it's tough to wrap your mind
around until you've done it once, then it's just a matter a typing and
bugfixing.

Along with the aforementioned Joy (which is a stunningly elegant language),
some other languages I find inspiring are rhoScript
([http://www.rhoscript.com/](http://www.rhoscript.com/)), Pico Lisp
([http://picolisp.com/wiki/?home](http://picolisp.com/wiki/?home)), and the
very clever WadC editor ([http://strlen.com/wadc-
editor](http://strlen.com/wadc-editor)), which implements a DSL and
interactive environment for describing Doom levels in code, rather than by
dragging vertices in a purely graphical editor (This isn't as crazy as it
sounds if you're unfamiliar with the limitations of Doom levels, since they
are constrained to certain types of simplified geometry that lend themselves
well to this).

In short, keep it up! I've never had to use any of these skills in my day-to-
day work (I'm not even a professional developer, though I'd like to be.) but
it's still a heck of a lot of fun to play around with.

[1] [http://billipede.net/2014/03/30/reverse-polish-
cowgirl.html](http://billipede.net/2014/03/30/reverse-polish-cowgirl.html) [2]
[http://billipede.net/2015/05/09/dawn.html](http://billipede.net/2015/05/09/dawn.html)
[3]
[http://billipede.net/2014/06/05/bedrock.html](http://billipede.net/2014/06/05/bedrock.html)
[4] [http://www.latrobe.edu.au/humanities/research/research-
proje...](http://www.latrobe.edu.au/humanities/research/research-
projects/past-projects/joy-programming-language) [5]
[http://billipede.net/2015/02/14/lets-write-a-
parser.html](http://billipede.net/2015/02/14/lets-write-a-parser.html)

------
mud_dauber
Any chance that this is inspired by Forth?

~~~
Drahflow
Define "inspired". I became aware of Forth while implementing Elymas. But the
decision to make it stack based was actually because I was too lazy (after
some attempts) to implement a correct LALR-parser-generator.

~~~
userbinator
If you want a more conventional syntax, I'd suggest trying with a recursive-
descent/precedence-climbing parser.

------
jetpm
Can I do this with strings as well?

"tsch" ==pa

pa dump

# "tsch"

~~~
Drahflow
;) Yes. It works exactly as you envisioned it. You can do it with pretty much
everything, actually:

    
    
      |dump =*clap
      [ "pa" |dump /tsch < > 0.0 ] ==slow slow clap
      # [
      #   "pa"
      #   <function: 00006000001CCD00>
      #   "tsch"
      #   <scope: 00006000004B3360>
      #   +0.0e0
      # ]

