Designing a new programming language for Arduino

Latest upate: link to post

Test the language: http://webcloudtools.com/sprk/lang-test/#hello-world

Project on GitHub: GitHub - YemSalat/spark-lang: Sparklang, aka Sparc(k) compiler; New experimantal programming language for Arduino and microcontrollers.

Hi everyone, I've been away from the forum for a while, but recently I have been lurking around, reading the forum posts, being amazed at how often some of the beginner questions come up. And I started thinking:

What would a language designed specifically for Arduino beginners look like?

I think many would agree that even though Arduino provides a lot of helpful materials (libraries, examples, etc.) - the language that it is based on, C++ - can still be a pretty big obstacle in getting beginner projects done.

Here is a short list of things that in my opinion could be improved if there was a language designed specifically for Arduino beginners:

Simplify syntax, remove the 'cruft'

C++ has a pretty complex syntax, which is full of semicolons, star symbols, parenthesis, etc.
By removing most of this stuff the language would look much more approachable (think Python/Ruby).
For example start by making semicolons optional and allowing for simpler code structures.
E.g. what a for loop variation could look like:

a = 25
[color=#5f3e31]repeat[/color] 10 times { a += 5 }

Inferred types instead of explicit declaration

Don't get me wrong - I am all for strictly typed languages, especially when there is almost no other way around it on embedded systems. But having to declare types, while very important in terms of programming techniques - has very little to do with what the beginner is trying to achieve, mainly finishing their project.

Better error messages

For example instead of saying something like ".. expected ')' before '{' token or .. at line at line .."

It could say - "You are missing a ')', make sure all your opening and closing parenthesis match on line .."
And overall all the errors could be more beginner friendly.

Tailored to the environment

How many times did you have to tell people that they should not use C++ Strings when programming for Arduino? Wouldn't it be nice if things like that were handled on the language level.
Apart from that, I think it would be very helpful to have some entities from the Arduino and micro controllers realm be present in the language. For example, it could have interrupts 'built-in' as a language structure, etc.

For example setting up an interrupt like this:

[color=gray]-------------------------[/color]

[color=#5f3e31]interrupt[/color] [b]when[/b] pin 12 [b]is[/b] RISING {
    // do stuff..
}

[color=gray]-------------------------[/color]

Convention over flexibility

A 'predefined path' can be very helpful to beginners. Languages that allow less flexibility and more conventional approaches to solving common problems tend to be easier to learn as they allow to focus on the primary goal without thinking too much about the implementation itself.

Taking care of performance issues and errors

Having a language that follows strict conventions - allows for better optimizing code and also preventing errors.
For example - the compiler can check if a variable is ever used inside an interrupt - and make it volatile if the user forgot to do so.

Handy stuff

Some things in Arduino are harder to do then they should be. Things like concatenating strings, checking if one string is contained in another one, etc.
Wouldn't it be great if you could just write:

foo = [i]"Hello"[/i]
foo + [i]" World"[/i] [color=gray]// "Hello World"[/color]

Different approaches

Perhaps it would be good to try different approaches to programming. A semi-declarative way of programming could be easier for beginners to grasp.
Set up everything, then assign what happens when (e.g. when sensor reading is higher then X - turn on the pump)

Here is a quick 'sketch' of what it could look like.

A program where an LED light blinks when a button is pressed:

[color=gray]-------------------------[/color]

[i]device[/i] [color=green][b]LedLight[/b][/color] {

    [color=#5f3e31]write:[/color]  pinLed [color=gray]// pin number[/color]

    [color=#5f3e31]action:[/color] [color=blue]blink[/color] {
        pinLed = [b]HIGH[/b]
        wait [b]5s[/b][color=gray] // does not prevent other code execution[/color]
        pinLed = [b]LOW[/b]
    }
}


[i]device[/i] [color=green][b]Button[/b][/color] ( [i]LedLight led[/i] ) {

    [color=#5f3e31]read:[/color] pinButton
    
    [color=gray]// no need for multiple IF statements[/color]
    [b]when[/b] pinButton [b]is[/b] HIGH {
        led ->[color=blue] blink()[/color]
    }
}

[i]led1[/i] = [b]create[/b] LedLight on pin 9
[i]button1[/i] = [b]create[/b] Button on pin 1

[color=gray]-------------------------[/color]

What do you think? Do you reckon any of these ideas are worth considering?

What in your opinion should a beginner-oriented Arduino language look like? Is such a language even needed?

I am gonna try and come up with more uses cases where such approach can be useful, and who knows maybe one day I'll even make it happen :slight_smile:

[ADDED]
Here is how I see it working:

device is the main entity in the language (think Class)

Every device follows this structure:

[i]device[/i] [b][color=green]DeviceName[/color][/b] ( [i]constructor parameters[/i] ) {

    [color=#5f3e31]write:[/color] pin1, pin2, pin3 [color=gray]// pins that the device can write to[/color]
    [color=#5f3e31]read:[/color] pin1, pin2, pin3 [color=gray]// pins that the device can read from[/color]

    [color=gray]// Here go predefined blocks that are built into the class[/color]
    [color=#5f3e31]init[/color] { ... } [color=gray]// basically constructor[/color]
    [color=#5f3e31]actions[/color] { ... } [color=gray]// all object 'methods'[/color]
    [color=#5f3e31]always[/color] { ... } [color=gray]// this code is executed all the time[/color]
    ....

    [color=gray]// then goes a list of all 'events' - code that executes when a condition is satisfied[/color]
    [color=gray]// they all start with keyword 'when'[/color]
    [b]when[/b] pin1 [b]is[/b] HIGH { ... }
    [b]when[/b] pin2 [b]is <[/b] 512 [b]and[/b] pin3 > 128 { ... }
    [b]when[/b] pin4 [b]is[/b] RISING { ... }
    ...

}

So there isn't much code outside the devices. (There can be other entities though, like timers for example, with their own set of "actions" and "events")
PS I do appreciate any criticism though, as it is entirely possible that I am missing some huge flaws in this.

If you can write the compiler, go for it. Once started, you'll see the actual effort required to do this task.
What are you going to write it in?... C++??

I think this is probably more appropriate for the Bar Sport section until you come up with a first working draft of your compiler.

(By the way, I agree with a lot of what you say.)

Making the compiler might not be monumentally difficult if you create a program to translate your code into C/C++ that could be processed by the Arduino IDE.

You may be interested in this Mirah project. Look for the Blogs by Charles Nutter who created it. He is very clever and claims that the underlying system can be used for other cross-converting projects.

...R

Syntax is the easy part. Anyone can learn the syntax. The hard part about programming is the logic and that's the same in any language.

Of course I am not planning to write my own compiler. Just write a grammar in some appropriate notation and use a compiler-compiler to generate the parser.

I wrote a few toy languages back at uni, with modern tools it is really not that hard (relative to writing your own compiler by hand)

The 'hardest' and most interesting part would be coming up with appropriate language structure. If we can come up with something useful - I will generate a compiler for it.

Robin2:
Making the compiler might not be monumentally difficult if you create a program to translate your code into C/C++ that could be processed by the Arduino IDE.

That is definitely one way of doing it, plus the Arduino IDE would also take care of all the other parts of the toolchain.
Since it accepts pure C/C++ - the compiler will just need to generate the code which fits with the setup / loop routines.
This way would also be easiest for people who don't already have the Arduino IDE installed

[EDIT] Sorry, I think there might be a confusion here, when I say 'compile' I actually mean transpile the language to C/C++ and then just use either Arduino IDE or avr-gcc directly to compile it to machine code. Writing my own compiler for avr would be crazy, I agree :slight_smile:

Delta_G:
Syntax is the easy part. Anyone can learn the syntax. The hard part about programming is the logic and that's the same in any language.

I disagree, syntax has major effect on how easy it is to understand the code, plus syntax is not everything, the way language is structured is very important as well. Compare C to x86 Assembler for example.

We surely don't need yet another language. Whilst it may at first appear that using C++ as the language for Arduino is a hurdle I see it as a positive advantage. There is tons of help already available in this forum and elsewhere on line if people are willing to look for it or ask questions.

If a new language is to be used then there will initially be no experts or experience in its use and no reference material to go to. When users want advanced features they will either need to switch to another language, probably C++, or the new language will need to have them built in, adding more complication again.

Just thinking of how some potential tasks can be solved with the proposed approach.
For example, rotating a stepper motor based on potentiometer reading (basic)

[i]device[/i] [b][color=green]Stepper[/color][/b] {

    [color=#5f3e31]write:[/color] pinMotor [color=gray]// pin numb er[/color]

    [color=gray]// initialize[/color]
    [color=#5f3e31]init[/color] {
        degrees = 0
        self -> [color=blue]rotate( [i]degrees[/i] )[/color]
        wait 500ms
    }

    [color=gray]// all object 'methods'[/color]
    [color=#5f3e31]actions[/color] {
        rotate ( int deg ) {
            pinMotor = deg
        }
    }

}

[i]device[/i] [b][color=green]Potentiometer[/color][/b] ( [i]Stepper st[/i] ) {

    [color=#5f3e31]read:[/color] pinReading

    [color=gray]// repeat actions within this block continiously[/color]
    [color=#5f3e31]always[/color] {
        st -> [color=blue]rotate( [i]pinReading[/i] )[/color]
    }

}

[i]stepper1[/i] = [b]create[/b] Stepper on pin 9
[i]potentiometer1[/i] = [b]create[/b] Potentiometer on pin 1

[EDIT] @UKHeliBob, sorry, did not notice your reply at first.

UKHeliBob:
We surely don't need yet another language. Whilst it may at first appear that using C++ as the language for Arduino is a hurdle I see it as a positive advantage. There is tons of help already available in this forum and elsewhere on line if people are willing to look for it or ask questions.

I do not disagree with you, Arduino does have a great (and huge!) community, yet I think it can be useful to think of other ways of solving project-related programming tasks

If a new language is to be used then there will initially be no experts or experience in its use and no reference material to go to. When users want advanced features they will either need to switch to another language, probably C++, or the new language will need to have them built in, adding more complication again.

Well, there can be basic documentation and examples :slight_smile: I think the question of "advanced language features" is not relevant for many Arduino users (which is fine) I think the community might be loosing a lot of people because the technology could be more beginner-friendly. Surely if people want more advanced features - they can use more appropriate tools for that.

device Stepper {

    write: pinMotor // pin numb er

    // initialize
    init {
        degrees = 0
        self -> rotate( degrees )
        wait 500ms
    }

    // all object 'methods'
    actions {
        rotate ( int deg ) {
            pinMotor = deg
        }
    }

}

device Potentiometer ( Stepper st ) {

    read: pinReading

    // repeat actions within this block continiously
    always {
        st -> rotate( pinReading )
    }

}

stepper1 = create Stepper on pin 9
potentiometer1 = create Potentiometer on pin 1

I don't see how this is any easier to understand or follow than the equivalent C++ code. All you've really saved anyone from is a missing semicolon error, and I think that should be the least of the worries. Most people can get the semicolon there. That's not so hard. With this code there is just as much structure to figure out, it's just different.

potentiometer1 = create Potentiometer on pin 1

Take this line for instance. How is this any easier than creating a potentiometer class in C++ and putting it in a library for the noobs so they can write.

Potentiometer myPot(1);  // creates a pot on pin 1

and later

int val = myPot.read();

You've just added 3 new keywords to learn and get right, create, on and pin.

Delta_G:

potentiometer1 = create Potentiometer on pin 1

Take this line for instance. How is this any easier than creating a potentiometer class in C++ and putting it in a library for the noobs so they can write.

Potentiometer myPot(1);  // creates a pot on pin 1

and later

int val = myPot.read();

The point of this is not just a different syntax, but different approach to the whole program structure.
Everything follows a strict convention and a lot of the stuff comes 'out of the box'
Timing is handled for you, so you don't need to worry about delay() halting your program flow.

You would loose some flexibility, but I think many things can be taken out if the language is aimed at beginners (pointer arithmetic for example)

Here is how I see it working:

device is the main entity in the language (think Class)

Every device follows this structure:

[i]device[/i] [b][color=green]DeviceName[/color][/b] ( [i]constructor parameters[/i] ) {

    [color=#5f3e31]write:[/color] pin1, pin2, pin3 [color=gray]// pins that the device can write to[/color]
    [color=#5f3e31]read:[/color] pin1, pin2, pin3 [color=gray]// pins that the device can read from[/color]

    [color=gray]// Here go predefined blocks that are built into the class[/color]
    [color=#5f3e31]init[/color] { ... } [color=gray]// basically constructor[/color]
    [color=#5f3e31]actions[/color] { ... } [color=gray]// all object 'methods'[/color]
    [color=#5f3e31]always[/color] { ... } [color=gray]// this code is executed all the time[/color]
    ....

    [color=gray]// then goes a list of all 'events' - code that executes when a condition is satisfied[/color]
    [color=gray]// they all start with keyword 'when'[/color]
    [b]when[/b] pin1 [b]is[/b] HIGH { ... }
    [b]when[/b] pin2 [b]is <[/b] 512 [b]and[/b] pin3 > 128 { ... }
    [b]when[/b] pin4 [b]is[/b] RISING { ... }
    ...

}

So there isn't much code apart from within the devices. (There can be other entities though, like timers for example, with their own set of "actions" and "events")

There would be a small runtime that would take care of timing and executing events.
PS I do appreciate any criticism though, as it is entirely possible that I am missing some huge flaws in this.

YemSalat:
PS I do appreciate any criticism though, as it is entirely possible that I am missing some huge flaws in this.

Absolutely. It's nothing personal. Every idea needs skeptics. That's how we weed out the shite. We don't always see the flaws in ideas we're too close to.

I'm with you that it might be fun to create a new set of syntax and for some projects it might be useful. I don't see how procedural code would work here once the plan got much bigger than read the pot, scale it, and write PWM to the led. I'm afraid this would run out of usefulness once the code got any bit of complicated and then the noob would have to go back to square 1 learning C++.

Delta_G:
I don't see how procedural code would work here once the plan got much bigger than read the pot, scale it, and write PWM to the led. I'm afraid this would run out of usefulness once the code got any bit of complicated and then the noob would have to go back to square 1 learning C++.

That's a fair point, that's why I am trying to come up with various use cases where it can be applied.
Overall I am planning to get away with 3 main entities for now: device, timer and state machine. I just haven't settled on all the concepts yet. If someone is planning on writing a web server or something like that - this would most likely not be the right tool for the job. I think it would be more well-suited for home automation projects and things like that.

Also, its worth noting that a lot of those projects never get "much bigger than read the pot, scale it, and write PWM to the led"

@YemSalat, what you are proposing will not really benefit from discussion.

If you can start a Thread in the Other Software Development section with a working version of your "transpiler" so that people can try it out you may get converts.

I would like a Python-like syntax simply so that I don't get confused switching between Python and Arduino code.

I was almost tempted to say I would like a Ruby-like syntax, except that I abandoned Ruby in favour of Python simply because Python has a better infrastructure and is more widely used (at least in the Arduino context).

...R

Have you looked at https://micropython.org/ ? I keep meaning
to and see if its a good fit for this kind of use (presumably its meant to be!)

I am a newbie to the Arduino IDE and am completely baffled by it's complexity. I think that C++ is a great language for experienced programmers, but lousy for beginners. Its syntax is cryptic, and mistakes are easily made, however, even with mistakes, the compiler still may be able to make sense out of it, resulting in incomprehensible results.
I think you should completely abandon C related languages as a choice, and make it more BASIC related. BASIC may make it slower, but can be improved by compiling it, rather than interpreted. It also has the advantage of being restricted in how many Statements can be used, not like C where there are unlimited functions available through its Libraries, but which are not that easily found by newbies.
BASIC has also the inherent advantage in that it is very user friendly and easily learned by non-programmers.

What do you think? Do you reckon any of these ideas are worth considering?

What in your opinion should a beginner-oriented Arduino language look like? Is such a language even needed?

OK, you asked...
Here are preamble statements :
Arduino is a brainchild of schoolteachers, albeit nobody will admit to that.
They put together nice piece of hardware, but stopped short to provide anything but very basic software.
( Most "libraries" are by folks outside Arduino )

That is on positive side of things.

On negative side - they bastardized perfectly workable language by hiding the foundation in the name of " not confusing the beginners". ( see the latest on 1.6.6. release)
The language foundation - C - is nicely documented in a skinny book of around 200 plus pages.
It is all in there and anybody who WANTS to learn it can read it over the weekend.
The C++ is just an addition , but EVERYBODY needs the foundation first.

Any time you scan this forum you can see that some folks just do not want to learn the foundation.
They just want to run robots!

You will not move Arduino from kindergartner level to first grade by having another language.

And I am not trying to discourage you, just telling the way I feel about things.

You do whatever floats your boat, but without Arduino.cc first removing the "do not confuse beginners " attitude you will be on your own.

Personally , if you could became member of Arduino inner circle of developers you could contribute more to everybody's benefit.

Cheers Vaclav

What I think might be more helpful would be a more noob friendly editor for the IDE. Something that spits out error messages that sound more like advice.

error: void value not ignored as it aught to be

could either be, or have in addition

this function does not return a value, so you can't assign it to this variable

Something that spits out an extra level of warnings like:

WARNING:  non-volatile variable never changes in body of while loop.  Loop will be infinite.

or even the ability to let people step through code so they can see their stuff getting hung up in a while loop or why an if statement seems to be "skipped".

I know in the java world there are code checkers that can even tell you for instance that a method is too long or does too many things and should be broken into individual functions. Or that you've done something else stupid. A code checker could be very useful for the noobs.

Basically, what I think would be useful would be to go through @PaulS's last 5000 posts and take the top 20 or so things he says and make compiler warnings out of them.

@MarkT will have a look, cheers

@hbl2015, I am not sure if basic is a good base, but I agree that having to look for various libraries can be confusing and it can be nice to have some 'essentials' built into the language

@Vaclav, thanks for sharing your opinion on this, but to be honest I have a pretty low chance of getting into the Arduino hq (not that I would want to anyway)

@Delta_G, I think it may actually be harder to rewrite all C++' errors and warnings then to make a separate language oO

@Robin2, I will probably have a go at writing a very basic transpiler in the next few days, which would allow you to just copy the code to IDE. I won't implement the main framework yet cause I have not completely worked it through, but I will try to add a bit of syntactic sugar at first (implicit types, nicer for/if statements, etc.)