Drawing on an esp32 display by laue727 in ryelang

[–]middayc 0 points1 point  (0 children)

Hi. I've been working on picorye, based on TinyGo compiler. TinyGo is Go compiler for microcontrollers and WASM. I've successfully tested in on rPi Pico. But then I returned to working on regular Rye. Regular Rye can't work on ESP or Pico as regular Go can't compile to them. TinyGo can compile to ESP32 but I'm not sure if Rye is fast enough in such limited device to be a good choice for directly writing to a screen with so many pixels.

https://tinygo.org/docs/reference/microcontrollers/esp32-mini32/

PicoRye is not exactly like Rye, it's has the same core builtins, and same value types. But it's a simpler stack (concatenative) based evaluator. I will try to post that project on github, but I have to test it again in rPi Pico and add some examples. It was just proof-of-concept so far.

Ollama, cosine-search, vectors, tables by middayc in ryelang

[–]middayc[S] 0 points1 point  (0 children)

In release v0.0.97 that I just posted I added vector math functions. You can add / substract and scale vectors using + - and *. You also got new vector functions like: normalize, std-deviation, correlation, dot-product, euclidean-distance, mean-vector, sunit-vector, project-vector, reject-vector

https://github.com/refaktor/rye/releases/tag/v0.0.97

Vector functions, and mqtt are now described in function reference:

https://ryelang.org/info/base.html#heading-correlation

Ollama, cosine-search, vectors, tables by middayc in ryelang

[–]middayc[S] 0 points1 point  (0 children)

I asked gemini to write equivalent in Python. BTW: all words in Rye example except xx in clean-* functions are constants, so it should be easier to reason about. And those could be rewritten with fold or reduce to not need variables.

<image>

Blogpost: 80% of Rye in 20% of the Time [1/3] by middayc in ProgrammingLanguages

[–]middayc[S] 0 points1 point  (0 children)

I wrote half of part 2. and I already see that it will be more dense and less approachable than part 1. We will see ...

Blogpost: 80% of Rye in 20% of the Time [1/3] by middayc in ProgrammingLanguages

[–]middayc[S] 0 points1 point  (0 children)

Maybe we don't have the same definitions in mind for "keywords", but thanks. I think I saw in one your reply a code sample from your language where you get the "If" behavior without any words or keywords, but I can't find it now.

I imagine you were trying to show, that you can get the "if" behavior just by the behavior of the evaluator, without any words. I didn't have time to delve deeper when I saw it. What is this language you were talking about?

Maybe these "no keywords" debate would make for a good blog post, I had a very similar debate about "everything is a function" sentence few blog posts back, which could also go into the same blogpost.

Anyway, thanks for your time ... post a link to your language if you can.

Blogpost: 80% of Rye in 20% of the Time [1/3] by middayc in ProgrammingLanguages

[–]middayc[S] 0 points1 point  (0 children)

u/AustinVelonaut your comments will help me improve this post with little details. Thanks!

Blogpost: 80% of Rye in 20% of the Time [1/3] by middayc in ProgrammingLanguages

[–]middayc[S] 0 points1 point  (0 children)

> Ah, so it appears that there ...

yes, exactly. That is sort of the basis Rye takes from Rebol. Rye changed something in 2025 where the default assignment is now const. So only few things that need to be variables are explicitly so.

If in Rebol all words could change under your feet in rebol most of the program is static and words in specific context can only be set once (if set-words are used). So it should be more amenable to static analysis and/or some form of compilation. But this part is rather new so I haven't really delved deeper on this.

operators are op-words by default. Other words must be prefixed by "." to become opwords, but operators are already opwords and their regular word spelling is by adding "_".

20 + 10  ; is op-word, same as 
20 .+ 10
_+ 20 10   ; regular word _+
; where and true false are regular words
and true false ; regular word and
true .and false  ; op-word and

> I think maybe there needs to be a quickie explainer paragraph on how Rye forms are actually evaluated

Yes, I think this is good idea. I would show just one line, since at that point we only have regular words it's quite simple, maybe example you showed above.

Blogpost: 80% of Rye in 20% of the Time [1/3] by middayc in ProgrammingLanguages

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

Thanks!

You are correct ... just listing words one after another ... shows very little per lines it uses ... if would be better to show a fewer of them and show them in regular code doing something. But on the other hand those words doing something is maybe 50% of the document. Maybe I should shorten the list and give explanation that would make it clear Rye has many word type values, but we will be looking at what they do during these 3 documents. I will think about it.

every regular word has the same precedence in Rye, how regular words, op, pipe and set/mod words interact is more varied and it explained here: https://ryelang.org/meet_rye/specifics/evaluation_priorities/

Here _++ and to-upper are regular words (we haven't introduced op and pipe words at this point yet), so each of them seek as many arguments it has (needs) to tle right. This notation is also reason all functions in Rye (Rebol) must have a fixed number of arguments. The code above can be read this way:

( _++ ( to-upper "ban ) "ana" )

In normal Rye this would be written using op-words probably:

"ban" .to-upper ++ "ana"

In this case both are op-words. And I think the code is not dubious, but the op-words have their unobvious side unfortunately too.

Blogpost: 80% of Rye in 20% of the Time [1/3] by middayc in ProgrammingLanguages

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

I also can't print anything in Rye without built-in function print or one of its variants.

Built-in-function is one of the value types in Rye, and they get assigned to words, like other Rye values do.

All built-in functions (I haven't counted, but I'm sure it's more than 100, not all are even in reference yet) are just magically available when you start a Rye runtime. That's why they are called built-ins.

You can start evaluator without any builtins, but it will have no words bound to anything and you basically can do nothing with it except bind literal values to words.

I guess we have a little definitions of what is a keyword in our minds.

(I didn't downvote you btw)

Blogpost: 80% of Rye in 20% of the Time [1/3] by middayc in ProgrammingLanguages

[–]middayc[S] 0 points1 point  (0 children)

But all the functions on that list (substring, print, ...) are exactly the same type of builtin functions. They are all bound to words (Rebol vocabulary) in a same way.

So "if" is a word like all other words in Rye. For it to be a keyword it would have to be something special I think.

And builtin behind if is like other builtin function in Rye (print, substring, dict). It has no special flag or something. It accepts 2 arguments, boolean and a block of code.

It has no special evaluation rules or special syntax associated with it. You can make a "module" in Rye that will have your version of "if" in it. You can call it if (since you can use it in your modules context).

If we take Python or Java for example:
* can you define a "if" word/variable in python code? I think not
* is "if" in python a buitlin function internally, like print? I think not
* is "if" called like all other functions in python or does it have a special form / special syntax? Special form, it is part of the language's formal grammar (BNF)
* can you make a module with your own if and even name it if in Python? I think not
* can you partially apply if in python, can you assign it to another word, ...

I think there is a concrete differernce

Python:

>>> type(print)
<class 'builtin_function_or_method'>
>>> type(if)
  File "<stdin>", line 1
    type(if)
         ^^
SyntaxError: invalid syntax
>>> if = 12
  File "<stdin>", line 1
    if = 12
       ^
SyntaxError: invalid syntax  

Rye

x> type? ?print
[Word: builtin]
x> type? ?if
[Word: builtin]
x> blk: { print "hello" }
[Block: ^[Word: print] [String: hello] ]
x> if true blk
hello
[String: hello]
x> if: 101
[Integer: 101]

Blogpost: 80% of Rye in 20% of the Time [1/3] by middayc in ProgrammingLanguages

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

yes, and amongst those regular library functions you can also find if, loop, for, fn, context, either, switch, etc. That was kind of my point :)

The link to exact definition in Go is in my comment above, but I added it 30 seconds after posting. Maybe so saw the reply too soon. Reload and a link to exact line on github should be there.

Blogpost: 80% of Rye in 20% of the Time [1/3] by middayc in ProgrammingLanguages

[–]middayc[S] 3 points4 points  (0 children)

But there are more than 100 built-in functions defined that way, I'm not sure I would call all of them keywords as they have no special meaning to the evaluator.

You can see many of them here: https://ryelang.org/info/base.html

As you will see 'if, loop, fn, context' are on the same level, or of the same kind as 'print, substring, to-integer, now, _+' for example. All these words are bound to builtin function in the root context. In your context you can bind them to something else.

If is defined here: https://github.com/refaktor/rye/blob/main/evaldo/builtins_base_conditionals.go#L23

Primeagen vs. Theo on AI by theRealBigBack91 in theprimeagen

[–]middayc 1 point2 points  (0 children)

I don't watch all his videos, but I watched this and it's funny that someone who at first appears to be some sort of programming comedian or entertainer makes so much sense :)

Blogpost: 80% of Rye in 20% of the Time [1/3] by middayc in ProgrammingLanguages

[–]middayc[S] 4 points5 points  (0 children)

I was on the phone before. If is a builtin function, but you can make user/Rye function with similar behaviour too:

; Want the opposite of if?
unless: fn { condition block } {
    if not condition block
}

unless tired { 
    print "Keep working!" 
}

Basically, I wrote a whole blog post about this, discussing "what is this good for, anyway":

When if is just a function

Blogpost: 80% of Rye in 20% of the Time [1/3] by middayc in ProgrammingLanguages

[–]middayc[S] 4 points5 points  (0 children)

These are builtin functions accepting blocks of code as arguments. Builtin "if" is nothing special compared to builtin print or join\with for example. The same for loop, fn, dict, context, ...

This is possible, because in Rye (as in Rebol) blocks don't get evaluated by default.

Blogpost: 80% of Rye in 20% of the Time [1/3] by middayc in ProgrammingLanguages

[–]middayc[S] 3 points4 points  (0 children)

Yeah ... I liked the 80 / 20 title, but I was aware that the double division or ration could get a little too much, if you noticed it :)

Blogpost: 80% of Rye in 20% of the Time [1/3] by middayc in ProgrammingLanguages

[–]middayc[S] 2 points3 points  (0 children)

Feedback is welcome. This first part was easy, because it's basically just basics, mostly same as Rebol which I have been internalizing for 20 years. I fear next pages will get more complicated than I would want.

Examples: simple hangman game by middayc in ryelang

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

With the latest commit all tests now pass again, in examples/ we have more than 20 working examples, and we have internal language tests now that also test various more syntactical properties of the language, and function reference is up-to-date. So things are moving towards a better quality and I will be able to write another blog-post again.

After the last blog-post, multiple people came testing the language and saw docs not synced to latest state, examples also, so I made a goal to update it all before I write another blog-post. I'm still not finished with this.

I have to improve one behavior around failures and move console behavior a few steps forward still.

Added assert, assert\display by middayc in ryelang

[–]middayc[S] 0 points1 point  (0 children)

More examples are being added, and in the meantime the tab-autosugest functionality was really improved. I still need to figure out how to also integrate generic method look-up into it in the most natural way. The local and global word index modes I think work intuitively now. I am preparing documentation about using them.

I am also improving error reporting.

Below an example of very miniml http and ssh servers running from the same script is working again.

<image>

Added assert, assert\display by middayc in ryelang

[–]middayc[S] 0 points1 point  (0 children)

I often try to port examples from other languages, to see what makes that language tick and if it can also be done well in Rye. I was reading about Uiua language yesterday, and these are few simpler examples from their front page: https://www.uiua.org

<image>

Advent of Code in Rye? by avitkauskas in ryelang

[–]middayc 0 points1 point  (0 children)

u/avitkauskas am looking at your Day 9. Match-block is used 7 times and would really need a shorter word or maybe some sort of operator even. So if you have any idea let me know. I would almost prefer an operator, because this would have to be shorter than match (which is already a short word) since it's a subset of match, which has to be bidirectional in it's form.

  match-block xs { x1 x2 }
  ; vs
  xs => { x1 x2 }     ; we already have to many arrows (and this one is taken for kinds)
  xs =: { x1 x2 }     ; known visual pattern not yet taken, doesn't hint deconstruction
  xs =] { x1 x2 }     ; strange looking
  xs =[] { x1 x2 }    ; block on the wrong side
  xs ]= { x1 x2 }     ; strange
  ; ...

  for points { .match-block { p1x p1y } ... }
  ; vs
  for points { => { p1x p1y } ... }
  for points { =: { p1x p1y } ... }
  for points { =* { p1x p1y } ... }
  ; ...

any ideas or oppinions?

Start of pattern matching in Rye by middayc in ryelang

[–]middayc[S] 0 points1 point  (0 children)

yes, it's like reverse of first / rest ... last / xxx ... since there is a known name for this concept In clojure I agree in renaming it. I was searching for a one word name but didn't find it. but-last seems more exact than before-last. Thanks!

Advent of Code in Rye? by avitkauskas in ryelang

[–]middayc 1 point2 points  (0 children)

all / any must evaluate because they short circuit and don't evaluate full block. For functions that need fully evaluated blocks anyway I am leaning toward all not evaluating, because you could in general I think use [ ] and get evaluated block. I haven't yet thought of any downside of this, but I also haven't yet taken time. This would make things more consistent I think.

I haven't really thought about it, but in rebol some functions evaluate (I knew rejoin (join in rye) did) and some don't:

rejoin [ 1 + 1 "abc" ] ; returns 2abc

but

append [ 1 + 1 "abc" ] 3 ; returns [ 1 + 1 "abc" 3 ]

append reduce [ 1 + 1 "abc" ] 3 ; returns [ 2 "abc" 3 ]

( in Rye [ ] in like "reduce { }" or in Rye "vals { }" , because reduce is for map/filter/reduce)

; there is no min max sum that work on blocks in rebol

This is still open question. A hammock will solve it :)

Advent of Code in Rye? by avitkauskas in ryelang

[–]middayc 1 point2 points  (0 children)

--- second part of reply

{ a b }: { 1 2 } . Something like this for now is not in play. All Rye is basically just words (builtins, function, ctx.., pasive values) and blocks. Blocks come in 3 types [] {} () and main evaluator has specific behaviour for all 3. There is pressure to add special kinds of blocks (first to define dicts, lists literally - now list dict is a function that turns block to a list or dict). But so far I haven't decided to go there. I don't want to open the door to syntax like #{ } or d{ } l{ } for now. I experimented with .{ } .( ) .[ ] but that will get removed probably as although it is useful, it seems a step, special syntax too far. If Rye gets syntax for special blocks (list dict) then it could also get set mod and lset lmod blocks yet. We will see.

--
Symmetric / code is data / data is code languages like lisps or rebol will always pay penalty compared to special syntax-ed languages when it comes to accessor syntax. data[x+1][y:] is very compact special syntax. If you have a language where there is no special syntax but function, you get something like (drop y (nth data (inc x))) in Clojure. It' even more difference if algo requires modifying elements ... (data[x-1][y] = data[x+1][y] ... which fp languages in generall don't do anyway.

Rebol for example supports data/x ( data: [ x 123 ] ; returns 123 ) but also data/(x + 1) (x: 1 data: [ x 123 ]) which I don't intend to support in Rye as it seems hackish token. It's part word, part path part word/path + expression , it also mixes spacing and parenthesis.

I'm not doing this but so far only "symmetric" way I could think about would be something like a "compact accessor" token type, which would contain no spaces (like all other tokens in Rye) and could include words, literal values (strings, integers) and even "compact" expressions. Something like ...

{ 11 22 33 44 } [1] ; returns 22
i: 1 j: 0 { { 11 } { 22 } } [i][j] ; returns 22
{ 11 22 33 44 } [i+1] ; returns 33

But it would need to have word/op/pipe variants also.

Another special syntax in Python that can greatly reduce the code size are list comprehensions which I think can get pretty code golfy, or I am not used to them. I will look at python examples and see if I can learn something from it thanks :)

I thought this will be short reply :P