DEV Community

loading...
Cover image for Play: A new programming language that targets Web Assembly, based on Forth

Play: A new programming language that targets Web Assembly, based on Forth

robinheghan profile image Robin Heggelund Hansen ・1 min read

Today marks the first release of Play, a new programming language inspired by Forth.

Play might look a lot like Forth, but improves on the language in several ways. Play includes a strong static type system like the ones found in Elm and Haskell. All data structures are immutable, and side effects are tightly controlled, which leads to code that is easy to reason about.

Code written in Play is compiled to web assembly, which means it can run pretty much everywhere, even in browsers.

The goal of today's release is not to present a finished product, but rather give people an idea of what writing code in Play would be like.

To learn more, you can take a look at the website and toy with some examples at the playground.

Discussion (18)

pic
Editor guide
Collapse
sarini68 profile image
sarini68

Hi, I'm spending some time in having fun with Play. I have a first question (maybe a lot more after). What happens to values on stack, are they consumed after use? See e.g.

def: main
entry: true
: four-and-five +

What happens to 4 and 5 after they are summed?
It seems to me at the moment not clear how to manage values on the stack
Thanks,
m

Collapse
robinheghan profile image
Robin Heggelund Hansen Author

Great to hear you're enjoying Play!

It depends on the word, really. For + and other math words, the numbers will first be popped/consumed, then the result will be pushed onto the stack. So they're consumed as part of their use.

The type of + is Int Int -- Int. You can read that as: "consume two ints, produce one int."

If you for some reason want to retain values on the stack you can use dup (short for duplicate). So if you want to keep 4 and 5 on stack, but also the sum of them, you can do the following: four-and-five dup dup +. The resulting stack would be: 4 5 9.

Collapse
sarini68 profile image
sarini68

Many thanks for your reply!
Is there any way to see all the content of the stack at a given time and not just the last value on top of it? I am also trying to read documentation about Forth to have a clearer idea of the background, best, m

Thread Thread
sarini68 profile image
sarini68

If am not wrong, please tell me, I've tried your suggestion and with rotate applied three times I got 4 10 and 5, as if the dup applied to have 2 times 5, and ten is the sum of the two. I can not explain me why, thanks again for your attention! Best, m

Thread Thread
robinheghan profile image
Robin Heggelund Hansen Author • Edited

Is there any way to see all the content of the stack at a given time

Unfortunetly, no. But that's definetly something that can be done in a later release!

as if the dup applied to have 2 times 5

Ahh, I was too quick in my reply and got it wrong. The following would be more correct:

def: main
entry: true
: four-and-five # stack: 4 5
  dup # stack: 4 5 5
  -rotate # stack: 5 5 4
  dup # stack: 5 5 4 4
  -rotate # stack: 5 4 4 5
  swap # stack: 5 4 5 4
  + # 5 4 10
  rotate # stack: 10 5 4
  swap # stack: 10 4 5
  -rotate # stack: 4 5 10
Enter fullscreen mode Exit fullscreen mode

Now, this is quite horrid. This is way too much stack manipulation for my taste. However, in later alpha's there will be more powerful stack manipulation words, like a specific word for doing duplicates of the two top elements on the stack.

Thread Thread
sarini68 profile image
sarini68

Many thanks again for your reply. Agree with you about too much stack manipulation. Unfortunately I didn't get the same results you wrote in the comments. I'll try again to better understand if something I did was wrong. Just a last question, I was wondering to use rotate to explore the content of the stack. Does rotate work fine just with three values on the stack?
Best, m

Thread Thread
robinheghan profile image
Robin Heggelund Hansen Author

rotate only works with the top three values on the stack.

I'll make a note to improve the repl for Alpha 2 so it's easier to work with multiple values, so that you don't need to rotate. :)

Also, you could be hitting a bug or I could've messed up somehow. I wrote down my previous answers at the end of a long day and didn't double check anything.

Thread Thread
sarini68 profile image
sarini68

many thanks for your reply.
If this does not bother you, I'll let you know what I got after some more accurate checking,
best
m

Thread Thread
robinheghan profile image
Robin Heggelund Hansen Author

Doesn't bother me at all :)

Thread Thread
sarini68 profile image
sarini68

I was wondering about Play whether also words could be added to the stack as values; I know that you are very expert about functional programming (I saw your post about Elm and I discovered about Play in an Elm forum), so also Play could become a functional programming language, is this your vision?
best, m

Thread Thread
robinheghan profile image
Robin Heggelund Hansen Author

You can add a word to the stack using a quotation: [ some-word ].

You could then do stuff like [ 1 + ] map on lists.

Thread Thread
sarini68 profile image
sarini68

oh. thanks, I'll go and see this
best
m

Thread Thread
sarini68 profile image
sarini68

In trying to understand Play I am going to discover the new (to me) stack-oriented programming paradigm. I am looking at various languages, among the others, the one which seems at a more mature stage, Factor. May I ask you your vision about Play with respect to these other languages? Thanks! best, m

Thread Thread
robinheghan profile image
Robin Heggelund Hansen Author

The goal of Play is to be a general purpose programming language which focuses on immutability and controlled side effects. Factor favors mutable data structures. Play also wants to be fully portable by targetting web assembly.

In the future, I hope that Play can do all the things Factor can, and more.

Thread Thread
sarini68 profile image
sarini68

Thanks for your explanation. I hope so for your Play project!
I was figuring out the role of the stack in reaching Play's goals. Immunatibility and controlled side effects are keywords also for Elm, and, as far I've understood, the ELM architecture is designed to allow for this. Will the stack become the place of the world where side effects are controlled? The code of Play is pure inside, but effects act on the world mediated by the stack, but how ?(I was trying to imagine something as the Elm architecture data flow with a stack in the middle) It is also hard to me to keep distinct what happens on the stack (as an execution structure keeping both data and code (thanks to quotations)) and what happens to data defined by Play (I don't know if I explained clearly, I have some doubts and it is also difficult to describe them). By the way, thanks to some tests done in the Factor's listener, I was able to understand and to play with quotations also in Play's playground! Best, m

Thread Thread
robinheghan profile image
Robin Heggelund Hansen Author

I think all of this will become more clear as the project progresses. I'll definetly focus on improving the playground in future releases so it becomes easier to understand what happens on the stack. :)

But in comparison to Elm, here's what the counter demo in Elm could look like in Play:

deftype: Model
: count Int

defunion: Msg
: Inc
: Dec

deftype: Inc
deftype: Dec

def: init
type: Model
: 0 >Model

defmulti: update
type: Msg Model -- Model
when: Inc
  swap drop # get rid of message
  dup count> 1 + >count
when: Dec
  swap drop
  dup count> 1 - >count

def: view
type: Model -- (Html a)
: html/div attribute/empty
    html/button 
      attribute/init
           Inc attribute/on-click attribute/add
      attribute/finalize
      "Increment" html/text html/add-child
    html/add-child # button added to div
    "Count: " html/text html/add-child
    "count" html/placeholder html/add-child # creates placeholder
     html/button 
        attribute/init
           Dec attribute/on-click attribute/add
        attribute/finalize
        "-" html/text html/add-child
     html/add-child # button added to div
  swap # stack: Div Model
  count> "count" html/replace-placeholder # places count into placeholder
Enter fullscreen mode Exit fullscreen mode

This is just an example, it could very well end up looking differently, but I hope it makes things more clear.

Thread Thread
sarini68 profile image
sarini68

Many thanks for your prompt reply. I'll look at your code. Absolutely I agree with you, to involve people in playing with Play, it is very important to have the possibility to look at the content of the whole stack, as well as, to have the possibility to clear it. Using these features inside of the Factor's Listener gave me the opportunity to understand more easily the effects of my code. Best, m

Thread Thread
sarini68 profile image
sarini68

Thanks,
I looked and tested the code (for init and update, not view, as it seems not possible to use Html now).
I wrote a main fx to test the code. I attach the code here:

deftype: Model

: count Int

defunion: Msg

: Inc

: Dec

deftype: Inc

deftype: Dec

def: init

type: -- Model

: 9 >Model

def: inc
type: Int -- Int
: 1 +

def: dec
type: Int -- Int
: 1 -

defmulti: update

type: Msg Model -- Model

when: Inc

swap drop # get rid of message

dup count> inc >count

when: Dec

swap drop

dup count> dec >count

def: main
type: -- Int
entry: true
: init >Dec swap update count>