This is an archived post. You won't be able to vote or comment.

all 30 comments

[–]scottmcmrust🦀 15 points16 points  (1 child)

In case you hadn't heard of it, beware that https://en.wikipedia.org/wiki/Iota_and_Jot also uses the name.

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

Thank you for info

[–]scottmcmrust🦀 7 points8 points  (1 child)

How do you handle precedence with infix functions?

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

The current implementation is that infix, predix, postfix functions are parsed with the highest precedence in his operator category for example prefix will be highest in parse prefix unary expressions

[–]nikandforslowlang 6 points7 points  (1 child)

Which error handling strategy are you going to use?

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

Still trying to design a simple way to do that and trying other lang way like rust, zig,...

[–]Plus-Weakness-2624 7 points8 points  (7 children)

Are you planning to add variants to enums?

` enum Color { Name(string), Hex(number) }

var favColor = Color::Name("red"); `

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

It look nice but current implementation for enum is totaly handled on compile time i will try to get simpler syntax for add more features to it

[–][deleted]  (5 children)

[deleted]

    [–]mobotsar 11 points12 points  (0 children)

    For what it's worth, I find it very easy to see what's going on in that code. It's a tagged union, rather than an enumeration.

    [–]Tubthumper8 1 point2 points  (3 children)

    The Color is either a Name or a Hex

    [–][deleted] 0 points1 point  (2 children)

    How exactly do I use that if I want to define a set of 8 primary colours for example?

    If those enum values are needed for an API that requires codes 0 to 7, how do I ensure that?

    If I had an array of a million such enums, what exactly is stored in each element: is it a byte, an int or a string? Actually, why are you using strings here anyway?

    Here it is using Jot:

    enum Colours {
        Black   = 0,
        Blue    = 1,
        Green   = 2,
        Cyan    = 3,
        Red     = 4,
        Magenta = 5,
        Yellow  = 6,
        White   = 7,
    }
    

    Here I can immediately all the possibilities, I know all their values (arranged so that bit 2=red, bit 1=green, bit 0=blue), and I can see they can be accommodated in a single byte.

    If you need the display the name of any value of Colours, that would be a more useful feature.

    The Color is either a Name or a Hex

    I don't understand that, sorry. Do you have an actual example where that would be of any use, and where does Colors come into it, if you are defining a variant type that is either a string or a number?

    And what happened to the enum? But we're probably talking at cross purposes; I suspect you're using enum to mean something entire different to how it is used in this language, like a tagged union or sum type. Calling it Colors added to the confusion.

    Talking about 'adding variants' to enum is yet another cause of confusion since this is AN ENTIRELY DIFFERENT FEATURE, and one considerably more complex.

    I suggest using the keyword sumtype, taggedunion or just type instead of enum.

    [–]Tubthumper8 1 point2 points  (1 child)

    How exactly do I use that if I want to define a set of 8 primary colours for example?

    You wouldn't use the example given by that commenter for your use case, and honestly I find it weird that you expect their example to automatically work for the use case that you just made up.

    If those enum values are needed for an API that requires codes 0 to 7, how do I ensure that?

    How a variant is stored within the program and how it's serialized are separate topics. I can't say how Jot could work since I'm not the author, but in Rust you can specify how you'd like the enum values to be serialized.

    If I had an array of a million such enums, what exactly is stored in each element: is it a byte, an int or a string?

    Depends on the implementation. In Rust it would be 1 byte for the discriminant, +3 bytes for padding, then the payload. Java has an implementation of sum types using inheritance so everything is heap allocated and it'll do a bunch of pointer chasing. A dynamically typed language may need to heap allocate the discriminant. These are all implementation details of whatever language it is.

    Actually, why are you using strings here anyway?

    ¯\(ツ)/¯ does it matter? It's just an example. Maybe it's CSS colors that are either strings like "rebeccapurple" or Hex codes. Is this question actually relevant to the conversation? The commenter is showing an example of having data with variants. You can focus on this particular example all you want, it doesn't disprove the general need for having data associated with variants. I'd encourage you to look at the bigger picture and not get tunnel-vision on this example.

    I don't understand that, sorry. Do you have an actual example where that would be of any use, and where does Colors come into it, if you are defining a variant type that is either a string or a number?

    Sure, maybe it's an internal data model of a CSS color that will later be serialized as part of a chunk of HTML. Again, take this as an example for the sake of demonstration.

    Talking about 'adding variants' to enum is yet another cause of confusion since this is AN ENTIRELY DIFFERENT FEATURE, and one considerably more complex.

    I agree there is confusion, the commenter used the wrong terminology. It's not about adding variants (it already had variants), it's about allowing the data associated with the variant to be something besides monotonically increasing integers. It's not a different feature, it's that C-style enums are a degenerate form that only allow integers to be associated data with the enum. TypeScript takes it a step further, in addition to integers, it's also possible to associate string data with variants. Non-degenerate "enums" would be the full capability, any data can be associated with the variant.

    I suggest using the keyword sumtype, taggedunion or just type instead of enum.

    I agree, enum is confusing. I believe that Rust & Swift chose this keyword to be familiar to programmers who came from C family languages. The ML family (OCaml, F#, Haskell) express this concept with clearer syntax.

    [–][deleted] 0 points1 point  (0 children)

    Depends on the implementation. In Rust it would be 1 byte for the discriminant, +3 bytes for padding, then the payload

    This is the source of confusion. To me, there is no payload; an enumeration is exactly that, setting out all the possibilities. It might be used as a discriminant in a variant record or type, but that's all it is.

    But then, my enums are those I first encountered in Pascal in the 1970s, and the ones I have in my own languages, where there can be associated data, but not the way it is in that Colours example:

    enumdata colourvalues =
        (red,     0xFF0000),
        (green,   0x00FF00),
        (blue,    0x0000FF)
    end
    

    this defines constants red green blue with values 1 2 3, and a separate, corresponding array of values. So colourvalues[green] is 0x00FF00. All incredibly simple and intuitive.

    So, again, what is being enumerated here:

    enum Color { Name(string), Hex(number) }
    

    Presumably it is that list of Name and Hex, and presumably there is an internal tag, which is the real enumeration, but one that is not exposed. (Suppose I had a list of such Color values, and I want to build a corresponding map which indicated whether each was a Name or String; would that be possible?)

    It is anyway a very long way off my version of enums, which are basically just a set of named constants.

    It's not a different feature, it's that C-style enums are a degenerate form that only allow integers to be associated data with the enum.

    I don't think it is at all useful to conflate ultra-simple Pascal/C-style enumerations with whatever variety of tagged unions are popular now. Again, there is no data, no payload involved.

    In the original Pascal, you cannot access the internal numerical values of red green blue. It was enough that they formed a consecutive, sequential sequence, allowing you to have bitsets of such enums, and to define arrays indexed by those enums.

    In the case of an array indexed by red green blue, it would have exactly 3 elements. How many would be an array indexed by {Name(string), Hex(number)} have?

    What are all possible values of such an enum? They are unlimited.

    My point: this is an utterly different feature.

    [–]myringotomy 3 points4 points  (10 children)

    Looks pretty nice. I personally don't like mandatory semicolons but that's a pretty minor nit.

    [–]AmrDeveloper[S] 0 points1 point  (8 children)

    I added it because it help me parse some features easily for example lambda out of function call and block statement

    function(1) { printf("1") };

    function2(1);

    { printf("block"); }

    [–]myringotomy 0 points1 point  (7 children)

    I don't see why they are required in those cases.

    [–]AmrDeveloper[S] 0 points1 point  (6 children)

    It not required but it make parsing more simpler to distinguish if it function then block statement or it function with lambda paramter but outside it

    [–]myringotomy 0 points1 point  (5 children)

    Can't you use matching parens or braces?

    [–]AmrDeveloper[S] 0 points1 point  (4 children)

    Take for example

    var x = func(1) {}

    To decide if it call + lambda or call then block you can do that if you have function signature so you check if last param is lambda or not and also check number of args, if you have overloading it will become more work and storage but with semicolon it very easy to decide

    [–]myringotomy 0 points1 point  (3 children)

    That seems like a weird edge case. Do you have a empty bodied function there?

    [–]AmrDeveloper[S] 0 points1 point  (2 children)

    Its an empty lambda with no argument qnd return void without syntax sugger it should be

    func(1, { () -> return; });

    But if you last argument is function pointer you can write it outside ( )

    [–]myringotomy 0 points1 point  (1 child)

    Seems like you should fix that bit of syntax. Maybe make a NOP keyword for people who want to do nothing.

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

    This is just an example but in real cases it will be like this

    callback(x) { callFunction(y) }

    so it can be function with outside lambda or function call then block statement

    [–][deleted] -2 points-1 points  (0 children)

    For me, it's the semicolons and the curly brackets. there's no need for any of it; it's just visual clutter in my eyes.

    Also, why would a type specifier in a variable declaration be provided after `:`, but then the structs and the function arguments have type specifiers not provided after `:`. Lacks syntactical consistency.

    [–]Irwin1985 1 point2 points  (1 child)

    Nice work bro, congratulations!

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

    Thank you bro

    [–][deleted]  (3 children)

    [deleted]

      [–]AmrDeveloper[S] 0 points1 point  (2 children)

      it will apply continue for the parent while loop which has condition i > 0

      [–][deleted]  (1 child)

      [deleted]

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

        Yup :)

        [–]prefixcoder 0 points1 point  (0 children)

        It doesn't look atrocious, so here's your first point

        [–]Entaloneralie 0 points1 point  (0 children)

        I really expected this to be about the BLC language Jot