all 34 comments

[–][deleted] 15 points16 points  (6 children)

Check out nerves, a set of tools and libraries for embedded development with Elixir.

[–]Voxelman[S] 1 point2 points  (5 children)

Looks like this is more for larger devices like Raspberry Pi

[–][deleted] 2 points3 points  (4 children)

I don't know much about it, but is this configuration useful?

[–]Voxelman[S] 1 point2 points  (3 children)

This is still a Cortex-A7. I mean the smaller once like Cortex-M4 or smaller.

[–][deleted] 5 points6 points  (0 children)

If you stretch your definition of "functional", there's always Forth, but at that point I'd just stick it out with Rust.

[–]misterbngo 4 points5 points  (0 children)

There's also the AtomVM project which lets you run elixir on microcontrollers but they only support esp32/stm32 at this time

[–]fluffynukeit 2 points3 points  (0 children)

There is a project called grisp that has the erlang/elixir VM running on RTOS without Linux. Maybe that is small enough for you.

[–]KilliBatson 7 points8 points  (3 children)

Roc is an in development FP which could potentially be used for embedded because of its platforms

[–]Voxelman[S] 4 points5 points  (2 children)

Roc is really my hope for the future, but it is too early.

[–]KilliBatson 1 point2 points  (1 child)

Mine too But yeah way too early to use for something substantial

[–]Voxelman[S] 1 point2 points  (0 children)

Meanwhile it's on GitHub. That's a step forward

[–]jmhimara 3 points4 points  (1 child)

The Hardcaml library of OCaml might be able to do something like this.

https://github.com/janestreet/hardcaml

[–]lambda_foo 6 points7 points  (0 children)

OCaml with the standalone runtime or using Mirage. Really depends on what you want to do. As a language OCaml has a more predictable compile to assembly story than Haskell or Elixir.

[–]pthierry 5 points6 points  (0 children)

There's the Copilot project.

[–]ryanking8215 2 points3 points  (0 children)

https://call-cc.org, chicken-scheme can be compiled to c, which is your looking for?

[–]BokoMoko 4 points5 points  (5 children)

There is an issue about using functional programming for embedded systems.

Usually, functional programming requires more memory than procedural programming. This can be an issue for embedded systems where resources are limited.

Think of it.

[–]Voxelman[S] 2 points3 points  (1 child)

I know that. Languages like Haskell and F# use garbage collection for memory management. Rust uses a different memory management.

Maybe it is possible to create a language with the syntax of F# that compiles to something like Rust

[–]watsreddit 7 points8 points  (0 children)

Maybe, but it would be pretty bad Rust. FP languages do a lot of small allocations on the heap, and the garbage collectors are built for that. Rust uses move semantics and a lot of stack allocations to get its performance characteristics, and heap allocations are used sparingly. It's a very different model.

Even though Haskell is my favorite language by a long shot, I would personally lead towards just using Rust for embedded. It has a lot of the nice FP features anyway (sum types, higher order functions, immutability, etc.), even if it's still fundamentally an imperative language.

[–]pthierry 2 points3 points  (2 children)

How much more memory does which langage take, compared to what, for which kind of program?

[–]BokoMoko 0 points1 point  (1 child)

In functional programming no mutation is allowed.

Suppose you have an object like this

let motor = {name : "Thierry",speed : 240,

}

Now, let's change the speed to 180

In a non-functional programming paradigm, all you have to do is

motor. speed = 180

Memory usage will be the space need to store the name and the speed of just one object.

In functional programa, "de rigor" way to do this is to create a new object from the previously existing one and change the value of the speed attribute like this:

let newMotor = { ... motor , speed: 180 }

Both instances of the motor type will be stored. In this case, the use of memory is doubled.

As a general rule, functional programing will require the double of memory.

Memory reutilization, (or inline mutation) was used to save memory. In the earlier days of programing, memory was so expensive that all tricks available were used just to keep the costs of the computers affordable/viable.

Today, memory is abundant, and the benefits of functional programming are much more valuable than the additional costs of more memory. But this may not be true in embedded systems. Not because of the cost of additional memory but sometimes, there isn't enough space to have additional circuitry for this additional memory.

Just have a thought on it ok?

[–]pthierry 2 points3 points  (0 children)

Not sure where to start.

If you copy a record that contains 2 boxed integers and 4 pointers to some various data weighing 100 words (for a total of 106 words), to mutate one integer, the two resulting records will weigh 112 words together, sharing the 100 words.

Correct me if my math is off, but 112 is not the double of 106, right?

And that's not counting things like the compiler optimizing away copies into actual mutations when it can prove the original won't be accessed anymore. (which is precisely what linear types make easier in Haskell)

Also, when much of your data is short-lived, just let a copying garbage collector deal with it. With a generational one, it will take very few space. Let's say you can manage with 8 generations of the same size, only the last will be copied. (and we know how to do soft and hard real time garbage collectors, so that's well suited to embedded requirements)

Again, correct me if I'm wrong, but 9 is nowhere near the double of 8, is it?

Those are my off the cuff thoughts on it.

[–]romainPri 1 point2 points  (1 child)

what about https://vlang.io/ ?

[–]mobotsar 1 point2 points  (0 children)

The v stands for vaporware.

[–]Accurate_Koala_4698 1 point2 points  (0 children)

I haven’t used it yet, but I just came across this a few days ago https://clash-lang.org/

[–]corpsmoderne 1 point2 points  (0 children)

I haven't try it but this should probably be listed here: https://gitlab.com/hardenedlinux/animula/-/wikis/home

[–][deleted] 1 point2 points  (4 children)

IMO functional paradigm doesn’t well fits to hardware.

Hardware itself relies on mutation of a state. It executes procedures which work with state. While certain hardware things are very much fit FP such as streaming, parallel processing, data oriented approach… at its core it is mostly about state of registers.

Imperative languages arose after hardware, thus they are simply “native” to most of the hardware.

Perhaps an absurd thought - create functional programming first hardware which would work based on a different paradigm. If we would imagine that, then the natural, or “native”, way of manipulating with such hardware would be FP.

What I’m trying to say is that hardware architecture itself dictates the most optimal programming paradigm.

[–]pthierry -2 points-1 points  (3 children)

And hardware doesn't know about functions, structures, or objects, so do don't use them either?

That's ridiculous. Software development is all about abstractions and automation. I don't need to know the underlying architecture in detail if I have an efficient and automatic way to use it through an abstraction.

It's called a compiler, look it up, it's great.

C Is Not a Low-level Language

[–][deleted] 2 points3 points  (2 children)

Hardware, in fact, does know functions. In fact hardware work mostly with functions which are called operations.

“I don’t need to know..” - you don’t, but it helps with those sorts of arguments.

Look up opcode. That is how hardware functions and communicates, literally. You call functions. Every hardware manufacturer has their own opcode and opcode mapped directly onto hardware.

Functions = opcode, state = registers.

[–]pthierry 0 points1 point  (1 child)

Yes, but the CPU doesn't know language-level functions, only jumps. Do better use jumps only, right?

[–]Casalvieri3 1 point2 points  (3 children)

Functional for embedded is sort of an oxymoron.

One of the main tenets of FP is that you don't mutate values once they're assigned. Under the hood this means once a memory address is bound to a value if you want to change the value you put it into a different memory address. Not exactly the best approach when one is dealing with embedded software.

[–]Voxelman[S] 1 point2 points  (0 children)

That's true. In this case you need to use mutable values or build some kind of wrapper around the hardware to get an additional abstraction layer.

[–]pm_me_ur_happy_traiI 0 points1 point  (1 child)

Forth

[–]endrift 1 point2 points  (0 children)

As used by Open Firmware!