
Show HN: Cixl – a minimal, decently typed scripting language - sifoo
https://github.com/basic-gongfu/cixl
======
davegauer
I enjoy seeing new experimental languages. I really enjoyed working through
the README exercises. It's the _perfect_ way to document and teach a language
all in one go. The REPL worked great.

First, I love how you've chosen to have functions wait for the correct number
of arguments to exist on the stack before executing. I've often pondered how
to make Forth-like languages less painful to program - your solution is very
clever!

Speaking of clever, I felt very clever indeed when I took your infix equality
example:

    
    
        | 42 == 42
      [#t]
    

and it worked when re-ordered as postfix:

    
    
        | 42 42 ==
      [#t]
    

...indicating two things: 1) I actually understood what was happening and 2)
the language is coherent.

It's great that basic IO so simple with 'say' and 'ask'. That allows somebody
to jump in immediately and start making fun things!

    
    
        | let name ask 'Who are you? ';
        say $name
    

Love the syntax for lambdas: { ... }

What is the rationale for requiring function implementations of the same name
to have the same arity? Nevermind! I just answered my own question: because
functions need to know how many parameters to seek from the stack.

The literal values for function arguments is awesome - pattern matching!

I don't understand this example demonstrating an "index" for the function
parameter types:

    
    
        func: baz(x y Int z T0) $x + $y + $z;
    

I assume 'T0' is the aforementioned index? But I'm struggling to see how it
works from this example. Maybe I'm just missing an idiom from some other
language?

Bizarro Question: Is there any way you can 'delete' a function in the REPL?
For example, to be able to re-use the name 'foo' as a function with a
different arity. (It's fine if you can't. The ability would be useless in an
actual program.)

You have an error in the README example for "Argument types may be specified
in angle brackets...":

    
    
        | &+<Int>
      ...
      Error in row 1, col 6:
      Func imp not found
    

But at least I was able to guess the correct syntax, yay!:

    
    
       | &+<Int Int>
      ...
      [Fimp(+ Int Int)]
    

Dates: I'm confused about the lack of a function called 'year' (singular)
since 'day' and 'month' exist. Otherwise, I'm impressed. Dates are damned
hard.

Everything about this language seems to be aimed at maximum brevity without
sacrificing clarity. I like that a lot. Congratulations for getting this far
and I'll definitely be bookmarking this.

I would love to see some longer programs written in Cixl to get a sense for
what they look like and how they'd be structured.

How long have you been working on this? How long have you been dreaming about
it? And how it is pronounced (SIX-el, KIX-el)?

~~~
sifoo
First of all, thanks for taking the time. I'll try to address your questions
in the same order, feel free to yell if I miss anything.

'T0' will be substituted for the type of the first parameter (indexing starts
from 0) on evaluation, it's the most straight forward way of adding the
constraint that two parameters need to be the same type without specifying
which type. I should make the example clearer by specifying a less concrete
type for x.

Nope, no way right now. I realize it would be nice to have in the REPL but
functions use their index in the list of implementations to implement upcall
which means I have to figure out another way to do that fast for that to
happen.

The reason some fields have plural functions as well is because they have dual
semantics. You have both the total number of days and the specific day of
month, for example. The year only has one meaning. I guess you could alias
'years' to 'year', but then someone is going to wonder why it's there instead.
There's some more material on the reasoning behind dates/times in /devlog.

You pretty much nailed the heuristics I've been using to drive the design.
It's been cooking for quite some time but I only started working on the
implementation 3 weeks ago or so.

It's slowly getting to the point where it's possible to write more interesting
code. I'm waiting for a couple of bigger pieces to fall in to place first,
structs are up next.

The C in the name is derived from the host language, which would make that
SIX-el.

~~~
davegauer
Parameter types: Okay, I'm closer to understanding: "T0" means "Type number
0". But I'm still confused by the example:

    
    
        func: baz(x y Int z T0) $x + $y + $z;
    

z is the same type as the 0th type. I get that now.

But what's confusing me is that it looks as if x's type is unspecified. The
'Int' here belongs to y, right? I'm sure I'll slap my forehead when it's
explained to me...

Dates: I see what you mean about there not being a "year of the _"
semantically. But when formatting a date, I think of it as "year-month-day",
not "years-month-day".

You've made excellent progress in 3 weeks! Keep it up!

~~~
sifoo
Ok, now I get where you're going. x and y share the same type, just like 'int
x, y' in C. That's what happens when you try to explain two concepts at the
same time, my mistake. You have a point with the years, I'll add an alias for
now. That is the goal; I'm kind of depending on people chipping in to be able
to keep up the pace though, I had a nice runway set up for xmas but now the
pressure is on again.

~~~
davegauer
Param types: Ah, of course. I had a vague suspicion that was what was going
on. But my brain was overloaded. Yeah, one concept per example is ideal. :-)

'Year' alias: excellent! That's one of those "look and feel" things that can
make the transition to a new language so much smoother.

I was going to add something about "now comes the hard part after the initial
flurry of activity: steadily growing the language without losing the passion."
But I didn't want to end on a downer. I'm truly impressed with what you have
so far.

~~~
sifoo
Agreed, it needs momentum to keep going and that's where I could use some help
right now. But it also becomes less of a struggle since I don't have to
constantly invent the ground I'm walking on, and since it's now getting to the
point where interesting programs are becoming possible. As an example, adding
symbol support ([https://github.com/basic-
gongfu/cixl#symbols](https://github.com/basic-gongfu/cixl#symbols)) took about
30mins.

------
danbmil99
Sweet, shades of FORTH. Very retro yet timely

~~~
sifoo
The principles of Forth sit at the bottom of most languages, though most like
to keep that power to themselves. And I've always felt that the Forth language
suffered from being so damn dogmatic and protective about the obvious lack of
convenience. As an added bonus, it makes a nice contrast to the current trend
of crippling languages ever more to protect people from themselves.

------
maneesh
Cool! Why'd you make it?

~~~
sifoo
The fact that no one else was doing it started to feel like an obligation.
Cixl is an attempt to find a middle way; a more permissive, less religious,
yet modern and convenient approach to solving problems in code. Unlike most
other languages; it isn't very interested in reinventing or ruling the world;
and doesn't mind being embedded in and extended from other languages.

~~~
tytytytytytytyt
I was with you at first, but then your usage of semicolons went way overboard.

~~~
sifoo
Which usage of semicolons are you referring to? The only one I can think of is
using them to terminate definitions. I realize it's slightly unorthodox, like
most of cixl; but many languages seem to be fine with using semicolons to
terminate every single freaking statement, how is this worse?

~~~
davegauer
I believe the semicolons in question are in your comment, not in your
language.

~~~
sifoo
Ah, epic swoosh :) They fill a clear purpose as a step between commas and
periods, which allows putting more structure into sentences and helps express
meaning more clearly. I've been told that they're more commonly taught and
used in Europe than the US, and my first language was Swedish. On the other
hand I definitely write more code than otherwise, so that probably explains
some of my fascination with punctuation. In the end, languages are tools for
accurately conveying meaning; (see, there he goes) and whatever rules don't
contribute to that goal may safely be tossed out.

~~~
thinkpad20
Semicolons should be used to join two complete sentences while having a
“comma-like” flow (e.g. “I like cake; it tastes good”). I personally tend to
use them quite a lot (despite being American). However I generally don’t put
more than one in a sentence, which I think is somewhat standard. That being
said, I don’t think it’s considered an _error_ , per se, to do so.

~~~
pasquinelli
if you have a list where at least one element has a comma in it you should use
the semicolon to separate the elements, like the sibling comment by
spiceoflife says, so that would usually produce multiple semicolons in a
single sentence.

~~~
thinkpad20
Definitely. I meant that in the usage that I described (as a way to join
complete sentences) you generally only see one per sentence.

------
nicolashahn
"decently typed"?

~~~
sifoo
Well, from one angle it's statically typed; names never change their types
within a scope. It's also strongly typed, more so than common scripting
languages. On the other hand it has a very dynamic, gradual feel to it; to the
point where you almost don't notice. That and the fact that using the word
'decent' seem to upset a lot of people, which is an indicator of much needed
mental debugging.

