Key language features: * Uses aliases not pointers, so it's memory-safe * Arrays are N-dimensional and resizable * Runs scripts or its own 'shell' * Error trapping * Methods, inheritance, etc. * Customizable syntax
Key language features: * Uses aliases not pointers, so it's memory-safe * Arrays are N-dimensional and resizable * Runs scripts or its own 'shell' * Error trapping * Methods, inheritance, etc. * Customizable syntax
Beyond NNs, my use case to embed fast C calculations into the language to make scientific programming easier. But the inspiration was less about the use case and more about certain programming innovations which I’m sure are elsewhere but I’m not sure where — like aliases, callable function arguments, generalized inheritance, etc.
That’s a great list — most of those languages I’ve honestly never heard of..
The name came when I was living in Seattle and missed the sounds of east coast summer..
counter :: int
for counter in <1, 10-counter> (
print(counter)
print(" ")
)
Using backfor to count backwards is an odd choice. Why not overload for? backfor counter in <1, 9> print(counter, " ")
This is confusing to me. Maybe I'm misunderstanding the design principles, but the syntax seems unintuitive.The example I gave was strange and I’ll have to change it. Not sure what I was trying to show there. The basic syntax is just:
for counter in <1, 5> print(counter)
backfor counter in <1, 5> print(counter)
It’s not overloaded because ‘for’ is basically a macro, expanding to ‘iterate, increment counter, break on counter > 5’ where ‘>’ is hard-coded. If ‘for’ was a fundamental operator then yes, there would be a step option and it would be factored into the exit condition.
You’ve got me thinking, there’s probably a way to overload it even as a macro.. hmmm…
IMO it's poinless to distinguish synctactically between iterating forwards and backwards, specially if you also support things like for counter in <1, 5>.map({ return args[1] * 2) to irate on even numbers (the double of each number), rather than having to define a fordoubled macro. I mean, adding method like map and rev to ranges is more orthogonal and composes better. (See for example iterators in Rust)
Not that I don't like syntactic flexibility. I am a big fan of Ruby's unless, for example
I think what you’re suggesting would require the <a, b> syntax to produce a proper iterator type, which it doesn’t currently do. That’s definitely worth considering — then you could attach methods, etc.
Thanks for the suggestion! I’ll think about the best way to fix this..
How does it deal with use after free? How does it deal with data races?
Memory safety can't be solved by just eliminating pointer arithmetic, there's more stuff needed to achieve it
There’s actually no ‘free’, but in the (member -> variable data) ontology of Cicada there are indeed a few ways memory can become disused: 1) members can be removed; 2) members can be re-aliased; 3) arrays or lists can be resized. In those conditions the automated/manual collection routines will remove the disused memory, and in no case is there any dangling ‘pointer’ (member or alias) pointing to unallocated memory. Does this answer your question?
I agree that my earlier statement wasn’t quite a complete explanation.
Of course, since it interfaces with C, it’s easy to overwrite memory in the callback functions.
> There’s actually no ‘free’, but in the (member -> variable data) ontology of Cicada there are indeed a few ways memory can become disused: 1) members can be removed; 2) members can be re-aliased; 3) arrays or lists can be resized. In those conditions the automated/manual collection routines will remove the disused memory, and in no case is there any dangling ‘pointer’ (member or alias) pointing to unallocated memory. Does this answer your question?
Does this mean that Cicada will happily and wildly leak memory if I allocate short lived objects in a loop?
Why don't you just add some reference counting or tracing GC like everybody else
> 1) members can be removed;
Does this causes use after free if somebody had access to this member? Or it will give an error during access?
The safety comes because there is no way to access a pointer address within the scripting language. The main functionality of pointers is replaced by aliases (e.g. a = @b.c, a = @array[2], etc.). The only use of pointers is behind the scenes, e.g. when you write ‘b.c’ there is of course pointer arithmetic behind the scenes to find the data in member ‘b’.
Having said that, it is certainly possible for a C callback routine to store an internal pointer, then on a second callback try to use that pointer after it has fallen out of scope. This is the only use-after-free I can imagine.
Note that you can add multithreading later if you adopt message passing / actor model. Even Javascript, which is famously single threaded, gained workers with message passing at some point
i :: int | 1 reference
a := @i | 2 references
remove i | 1 reference
The data originally allocated for ‘i’ should persist because its reference count hasn’t hit zero yet.
I've been working on one for Kotlin lately:
smartmic•1w ago
[0]: https://janet-lang.org/
forgotpwd16•1w ago
briancr•1w ago
publicdebates•1w ago
briancr•1w ago
briancr•1w ago
One personal preference is that a scripting syntax be somewhat ‘C-like’.. which might recommend a straight C embedded implementation although I think that makes some compromises.
dualogy•1w ago
briancr•1w ago
zem•1w ago
briancr•1w ago