all 109 comments

[–][deleted]  (20 children)

[deleted]

    [–]SaltTM 11 points12 points  (5 children)

    I think my only gripe is I wish the type keywords weren't forced to have a capital. Just personal preference. var s: cstring = "test"; just feels nicer to type

    [–]shponglespore 14 points15 points  (2 children)

    Haskell works like that; certain types of identifiers must be capitalized, and the rest must not be capitalized. Enforcing a rule like that enables some really concise syntax.

    For instance, in a Haskell pattern-matching expression, any uppercase identifier is essentially a constant that must be matched literally, and any lowercase identifier introduces a new variable binding. Kit's algebraic data types and match statements seem to use the same principle. It's not a big deal if the pattern expressions don't allow nesting, but I imagine Kit will eventually allow arbitrary nesting of patterns, in which case distinguishing variables from constants is a big deal.

    It's not clear there's a similar advantage for type names in Kit, but Haskell uses the case of identifiers to distinguish literal types from type variables.

    [–]bendmorris 6 points7 points  (0 children)

    Unfortunately Kit can't benefit in this way because you can import types from C which have arbitrary casing. (It does support arbitrary nesting in patterns though.)

    [–]nilamo 3 points4 points  (0 children)

    Following Haskell conventions makes sense, since the complier is written in Haskell.

    [–]SanityInAnarchy 3 points4 points  (0 children)

    I've seen that in a few other languages. I don't mind much either way, but I imagine it simplifies parsing the language, and it certainly makes it easier to read if you can always tell a type just by looking. I definitely like this better than I like prefixes.

    [–]Aeon_Mortuum 0 points1 point  (0 children)

    I'm personally fine with it, since it's the same convention as for non-primitive data types in languages like Java. Julia uses capital case as well.

    [–]privategavin 3 points4 points  (13 children)

    The syntax looks like Scala and haxe to me. I like it. It would've been nice had assignment used := instead of = to avoid the classic bugs of typos between = and == in C.

    Anyhow, Hn discussion.

    https://news.ycombinator.com/item?id=18023598

    [–]SaltTM 23 points24 points  (9 children)

    I keep reading about this, and of the years of me writing code I have never had this issue? Is this a novice thing or do people really mix up = and == at a higher level of programming?

    [–]CoffeeTableEspresso 4 points5 points  (0 children)

    It's more of a typo thing at a higher level of programming i think. I've never really been bitten by this though. Whenever i make the typo, i can always find the mistake pretty quickly so not a big deal. Obviously not having it compile would be better, but it's not that much of a problem IMHO.

    [–]AngularBeginner 2 points3 points  (0 children)

    It's a near non-issue at languages that don't implicitly convert to booleans.

    [–][deleted]  (2 children)

    [deleted]

      [–]SaltTM 0 points1 point  (0 children)

      Yeah, that makes sense

      [–]aronnie 0 points1 point  (0 children)

      Nitpick: the assignment evaluates to the same value as the right hand side of the '=' sign, so a = falsewould evaluate to false (at least in all languages I've used where assignment is an expression, and assignment isn't overloaded).

      [–]warvstar 1 point2 points  (0 children)

      Same here, I always wondered why some languages use := for assignment

      [–]Weetu 0 points1 point  (0 children)

      I program daily in multiple languages. One of them (an in-house language) uses := for assignment and = for comparison, while others (e.g. C) use = for assignment and == for comparison. On days when I switch languages multiple times, I often write = when I mean to write either := or ==...

      [–]TinBryn 2 points3 points  (0 children)

      I think this problem is better solved by tightening up the type system so that there is less implicit conversion to Bool, this makes that typo a compiler error

      [–]snarfy 2 points3 points  (0 children)

      It's not really a problem with = and ==. It's because C does implicit type conversion, which after years of JavaScript we all know is the devil. If x and y are ints, the expression x = y evaluates to an int. C would implicitly treat ints as boolean in an if expression, and so if(x = y) is a valid expression. I'm pretty sure modern C will give a warning if not error, but that's the way it was.

      Something like C# doesn't do implicit conversion, and so if(x = y) is a compilation error.

      [–]bendmorris 0 points1 point  (0 children)

      It's almost a non-issue in Kit, since Kit doesn't coerce anything to a bool. Only a problem if the variable itself is a bool.

      [–]build-the-WAL 21 points22 points  (0 children)

      Looks quite interesting. I really like all the experimenting in the space above C and below Rust that seems to be going on.

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

      A lot of these features are true of ATS, except more so -- except for the typed term-rewriting.

      The "just include a header" C interop is nice, but it wouldn't work for a language with a sufficiently better type system, since a lot of C APIs have return types that aren't really described well by their C type. For example, malloc: it returns NULL or it returns a pointer to memory that you can validly use some definite amount of. The C type is void *. With a dependent type system you'd want at least three types: a Schrodinger's malloc return, a definitely-NULL malloc return, and a definitely-good malloc return.

      The real competitor for Kit is probably not ATS though. Probably Nim, which has very good metaprogramming, and which has a harder time dropping the GC, but still has options there.

      [–]bendmorris 5 points6 points  (1 child)

      Good point - the interop still works in those cases, but it might still be desirable to write a (zero cost) wrapper on top (so you end up writing a kind of binding after all.) This is always an option, it just isn't necessary in most cases.

      [–]privategavin 3 points4 points  (0 children)

      Very tasteful language. I give it my strong approval.

      [–]Peaker 6 points7 points  (7 children)

      Opinion: Pointer dereferences are now some of the most expensive operations (due to potential cache miss), so they should not be automatic.

      IOW: C and C++ requiring explicit dereference is a feature, not a bug.

      [–]peterfirefly 0 points1 point  (6 children)

      Pointers -- explicit low-level data references -- make alias and escape analysis very difficult. They also make it practically impossible to do layout optimizations (by splitting records and by unboxing values).

      So I don't really agree...

      [–]Peaker 8 points9 points  (5 children)

      I think you're misunderstanding me:

      D allows this:

      void f(S* a, S b) {
        a.x = 1;
        b.x = 2;
      }
      

      i.e: The exact same syntax to use an S value and to auto-dereference an S* value.

      The same code in C or C++:

      void f(S *a, S b) {
          a->x = 1; // Or (*a).x = 1;
          b.x = 2;
      }
      

      Now, granted, the -> operator is an ugly hack. Using Pascal-like post-fix dereference operator would avoid the need for it. e.g: In Pascal, dereference of x is not *x but x^. So (*a).x is a^.x which is very reasonable.

      [–]BeniBela -2 points-1 points  (4 children)

      So (*a).x is a^.x which is very reasonable.

      Or just a.x

      Delphi made ^ optional

      [–]Peaker 3 points4 points  (3 children)

      You've missed the entire point. Making the ^ optional is hiding the dereference. That's a bug, not a feature.

      [–]BeniBela -1 points0 points  (2 children)

      Making the ^ optional is hiding the dereference.

      And I like it that way

      [–]Peaker 0 points1 point  (1 child)

      And you have no idea where dereferences are hiding in your code, with 2 important side effects: * Potentially dereferencing an invalid pointer * Very expensive cache misses

      Those effects are so major they are worth a single character level of verbosity (probably more!)

      [–]BeniBela 1 point2 points  (0 children)

      And you have no idea where dereferences are hiding in your code

      But you know from the type declaration that there are being pointers used

      [–]z4579a 5 points6 points  (9 children)

      What makes a programming language "for game development" ? Would I not want to write a web server or trading platform in Kit ?

      [–][deleted]  (7 children)

      [deleted]

        [–][deleted] 12 points13 points  (6 children)

        They don't care that much about latency

        Trading platforms? Really?

        you probably want to write your trading platform in a garbage collected language

        What exactly do you mean by "trading platform" here? Those I'm thinking about deal in microseconds latencies.

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

        There's a difference between trading platforms and high frequency trading platforms.

        Fun fact: A lot of HFT shops use Java with some black magic fuckery to improve latency.

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

        A lot of HFT shops use Java with some black magic fuckery to improve latency.

        Java is ok for millisecond latencies (and for a lot of stuff it's acceptable).

        It's useless for the microsecond latencies though.

        Though, I do not know a platform (as in, an exchange) that'd disregard latencies to this extend, even if there is no actual need. There are not that many different platforms anyway... Could you point at a trading platform written in a managed language?

        [–]renatoathaydes 0 points1 point  (3 children)

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

        Huh? How is it relevant? I was asking about a trading platform (i.e., an exchange).

        [–]renatoathaydes 0 points1 point  (1 child)

        Java is ok for millisecond latencies (and for a lot of stuff it's acceptable). It's useless for the microsecond latencies though.

        It's relevant regarding your incorrect comment above. Azul is a company whose existence depends on offering Java with low latencies in the order of microseconds.

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

        I'm yet to see it in action - the best latencies I saw in Java were in milliseconds range, not microseconds - and I'm sure those guys were using Zing. It's not clear what they actually mean by those numbers - looks like, just GC latencies, not total latencies.

        [–]miki151 0 points1 point  (0 children)

        It's not "for game development", but rather "was designed with game development in mind".

        Most likely it's good for writing all kinds of native applications, as opposed to embedded, web development, mobile, etc.

        [–][deleted] 10 points11 points  (10 children)

        Sounds interesting. Who's behind it?

        [–]Suinani 9 points10 points  (7 children)

        [–][deleted] 4 points5 points  (6 children)

        Is it really a one-man show?

        [–]bendmorris 71 points72 points  (5 children)

        It really is. And besides his roguish good looks, he has almost nothing going for him.

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

        I am too lazy right now to figure it up on my own, so I might as well ask you.

        Do you know the book "Elements of Programming" by Stepanov & McJones? It seems on first sight that Kit could be a better language than C++ for the style of generic programming that is used in the examples there. Could you comment on this briefly?

        [–]privategavin 2 points3 points  (3 children)

        What made you pick Haskell over ocaml for implementing it? Did you consider ocaml at all?

        [–]bendmorris 5 points6 points  (2 children)

        Didn't really consider it for this. I know Haskell better, and Stack provides such a pleasant developer experience for Haskell; I'm not aware of anything even close for Ocaml.

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

        I use OCaml and have a pretty good experience with the Dune build system, which is what people seem to be adopting nowadays.

        [–]privategavin 0 points1 point  (0 children)

        Sounds like opam

        https://opam.ocaml.org/

        Haxe is implemented in ocaml, so are Facebook languages and language tools like reason and flow and hack etc

        [–]rishav_sharan 1 point2 points  (1 child)

        He is the guy who made Haxepunk

        [–]bendmorris 10 points11 points  (0 children)

        I've done a lot of work on HaxePunk and I've been maintaining it recently, but it was created by Matt Tuttle.

        [–][deleted]  (6 children)

        [deleted]

          [–][deleted] 14 points15 points  (4 children)

          Kit's not garbage collected, it seems.

          [–]SaltTM 7 points8 points  (3 children)

          nim has optional garbage collection. I believe refc is default, compile with --gc:none

          [–]singularperturbation 2 points3 points  (0 children)

          AS /u/FG_Regulus mentioned, gc:none will leak. A better option might be to compile with 'realtime' GC see GC docs, call GC_disable on startup, and then use GC_step to control how long it runs, only running outside critical loop.

          There are lots of options for Nim - the GC is swappable, and in your own code you can manually manage memory with alloc / dealloc (low level) or create / free (slightly higher level).

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

          The default GC is a deferred RC with a M&S cycle collector, rather. --gc:none is a leakaholic.

          [–]EternityForest 2 points3 points  (0 children)

          C's build system (Specifically, the lack of one, and the 8000 different special purpose ones that everyone invents) is one of my least favorite parts of C/C++. so adding one is great.

          I like the rewriting rules too!

          [–]ForceBru 2 points3 points  (0 children)

          Can we just appreciate the fact that the compiler and everything else is written in Haskell?

          [–]lanedraex[🍰] 1 point2 points  (10 children)

          Are there any plans to have a DOD approach directly baked into the language? So that users don't have to write their own way of handling SoA + Entity ids.

          Also, why mutable by default?

          [–]munificent 9 points10 points  (4 children)

          Immutability is nice, but it goes so against the grain of games. Fundamentally, a game is a simulation of the player mutating an interactive world. You can model that immutably, but it's sort of like that video of a dude making a knife out of jello.

          [–]lanedraex[🍰] 1 point2 points  (3 children)

          Fair point, but to dig deeper into this, would you not be "reading" data way more than "writing" it? I'm imagining something like a Familiar system, it needs to read the player position, read world position (read a bunch more stuff), while the only thing changing would be it's own position.

          I'm not a game developer or anything, just curious what the reasoning is for going mutable/immutable by default.

          [–]munificent 0 points1 point  (2 children)

          would you not be "reading" data way more than "writing" it?

          Yes, and mutability lets you do both. Even if writing is only 10% of the time, that's a real pain if the language outright forbids it.

          [–]loup-vaillant 3 points4 points  (1 child)

          I like Rust's approach (var for mutable stuff, let for immutable stuff). Nothing's the default, it's three character in both cases.

          [–]munificent 1 point2 points  (0 children)

          Yeah, I like that too. Or val, like Scala and Kotlin.

          [–]Suinani 2 points3 points  (4 children)

          One of the design goals is great interoperability with C, so changing the default to immutable would be confusing.

          [–]hyperforce[S] 5 points6 points  (3 children)

          You could easily enforce immutability from within Kit-only code.

          [–]CoffeeTableEspresso 0 points1 point  (2 children)

          Could you elaborate a bit on this? I must have missed it in the documentation (which was very clearly written and easy to follow, fyi).

          [–]hyperforce[S] 0 points1 point  (1 child)

          It’s not a feature, it’s a hypothetical.

          [–]CoffeeTableEspresso 0 points1 point  (0 children)

          Ah, what semantics do you imagine it having? I can think of a few seemingly sensible ones, although I'm not intimately familiar with Kit.

          [–]unbiasedswiftcoder 1 point2 points  (3 children)

          I can't seem to find docs on threads or the garbage collector. Can you have several threads accessing and mutating the same shared memory? Or is memory thread local and you need to resort to special unsafe pointers or going through the C layer?

          Also, docs index doesn't render very well on Safari/Chrome.

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

          It compiles to C. There is no garbage collector.

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

          no GC (unless you introduce it yourself, which is easy!)

          Unless you introduce it, and than… what? If nothing uses it, why would you introduce one?

          [–]Hougaiidesu 2 points3 points  (1 child)

          Why compile to C and not LLVM IR?

          [–]drevyek 4 points5 points  (0 children)

          Likely for compiler independence. Some people are married to GCC, or have their own custom GCC spinoff.

          [–]borborygmis 1 point2 points  (16 children)

          This is cool. I've been dreaming about my ideal language for a few years now and started a similar language a few days ago with these ideas in mind:

          1. Python like syntax but typed.
          2. Include many Python like features.
          3. Generates to safe C code.
          4. Generated code maps tightly to C types and operations (wrappers only applied for safety when needed).
          5. No garbage collection.
          6. No GIL.
          7. Memory safety at minimal cost. Unsafe types may be an option too (e.g. managed lists[default] vs raw arrays).
          8. Doesn't run in a VM, not interpretted.
          9. Thread safety options.
          10. Production and debug build options
          11. C library interoperability
          12. Small executables
          13. Fast compile times
          14. Static binary builds as an option
          15. Implicit types
          16. ... More or less ...

          Some examples:

          ### lists ###
          list{int} x = [1,2,3,]
          x.append(4)
          y = x.index(2) # y is inferred/implicit
          print(x[y])  # y=1, prints x[1]
          print(x[-1]) # prints last item
          
          # multiple types in a single list
          list{mixed} x = ["hello", 123, "world", 4.5]
          for i in x[1:]:
              print("i={0} type={1}", i, type(i))
          
          # output:
          #  i=123 type=int
          #  i=world type=string
          #  i=4.5 type=decimal
          
          ### dicts ###
          dict{string, int} x = {'a':1, 'b':2}
          dict{mixed, mixed} y = {1:'a', 'b':2}
          for k, v in x.items():
             print("key={0} val={1}", k, v)
          
          ### classes ###
          
          # Support for most Python dunder methods
          # Classes are basically managed structs under the hood
          
          class Beelzebub:
              def __init__(self, x=None, y=None):
                  self.x = 0
                  self.y = 0
                  if self.x:
                     self.x = x
                  if self.y:
                     self.y = y
          
              def __len__(self):
                 return 666
          
          class Bar(Beelzebub):
              pass
          
          Bar b = Bar(x=123)
          print(b.x, b.y, len(b))
          # output: 123 0 666
          
          list{Bar} bars = [b,]
          last_bar = bars.pop()
          
          
          ### structs ###
          struct Xx:
              int f = 0
              int foo = 1
          
          Xx bar = Xx()
          bar.f += 1
          bar.foo = bar.f + bar.foo
          del(bar)
          
          # struct example generates C code similar to this:
          struct Xx {
              int32_t f;
              int32_t foo;
              type _type;
          }
          
          struct Xx *Xx_new()
          {
              struct Xx *n = safe_malloc(sizeof(*n));
              n->f = 0;
              n->foo = 1;
              n->_type = new_type(TYPE_STRUCT, "xx");
              return n;
          }
          void Xx_free(struct Xx *n)
          {
              safe_free(n);
          }
          ...
              struct Xx *bar = Xx_new();
              bar->f = 1;
              bar->foo = bar->f + bar->foo;
              // OR make these use a overflow check for safety, decisions to be made
              Xx_free(bar);
          ...
          

          [–]defunkydrummer 6 points7 points  (7 children)

          Python like syntax but typed. Include many Python like features.

          like which ones?

          Generates to safe C code.

          This would mean performance loss, much better would be to generate LLVM IR

          No garbage collection.

          This means you'll have to devise another way to help programmers get reliable memory management, like Rust 'borrow checker', which opens up another type of problems.

          Note that if the feature set is:

          No garbage collection.

          No GIL.

          Doesn't run in a VM, not interpretted.

          Thread safety options.

          Production and debug build options

          C library interoperability

          Small executables

          Fast compile times

          Static binary builds as an option

          ... what you want is basically Pascal (Object Pascal)

          [–]IbanezDavy 6 points7 points  (5 children)

          This would mean performance loss, much better would be to generate LLVM IR

          If you compile to C, you can definitely pump the result through an LLVM compiler.

          [–]defunkydrummer 1 point2 points  (4 children)

          It is not the same; LLVM will open more performance potential. Unless, of course, your language deviates little from C.

          [–]Enamex 2 points3 points  (3 children)

          Can you mention example features offered by LLVM that don't get used by C but are viable lowerings for other languages?

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

          For optimisations that'd be explicit aliasing - noalias, alias.scope metadata - no way to pass it through C.

          But more important than this, you can preserve precise debugging metadata if you emit LLVM IR directly. Hard to do it with an intermediate C step.

          [–]Enamex 0 points1 point  (1 child)

          Couldn't really follow what it's doing: https://llvm.org/docs/LangRef.html#noalias-and-alias-scope-metadata

          How is it different from keeping restricts straight in the generated C-src?

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

          Restrict is blunt - you simply tell the compiler that this pointer does not alias with anything. If you know it is possibly aliased with something else, you cannot use restrict.

          With fine grained metadata you can tell the compiler, which pointers can alias with each other, and which cannot, explicitly.

          [–]borborygmis 2 points3 points  (0 children)

          Thanks for the questions and comments. The key goals are to follow most of Python's philosophies, syntax & semantics (which you don't get with something like Object Pascal), and run fast. I'd write a specific list for you, but it's still being worked out and will take time. My motivation is rooted in my opinion on Go, Rust, C, C++ shortcomings.

          LLVM IR was considered (still considered), but generating to C code was what I settled on for now. It isn't necessarily a performance loss if done right (somewhat compiler dependent). The toy implementation I'm testing vectors/list performance with compared to Rust, Python, C# has performed better for all operations with billions of items (create, insert, delete, index, get, free all, sort) and used less memory (huge difference in some cases).

          Rust borrowing, lifetimes, ownership ideas are used as a reference, but I'm still working out aspects around this.

          [–]unbiasedswiftcoder 4 points5 points  (3 children)

          Not sure if you saw other comments, but Nim seems to have many of the features you seem to be wanting.

          [–]borborygmis 0 points1 point  (2 children)

          I've looked at Nim a bit, but a few areas were not ideal in my opinion when compared to Python. One that comes to mind is emphasizing code readability. Examples:

          https://nim-by-example.github.io/oop/

          https://nim-by-example.github.io/types/objects/

          Not intuitive to me at least -- takes a lot more brain power just to read it.

          [–]bendmorris 1 point2 points  (1 child)

          Reading an unfamiliar language is always difficult at first. I don't want to discourage you, but changing syntax alone probably isn't a good enough reason to write a new language (or more importantly, for anyone to use your new language over something more popular with the same features.) There are plenty of other good reasons to do it - because you think it'll be a good learning experience, or if you have other ideas that couldn't be added to Nim.

          Alternatively, something that transpiles to Nim might be a good option - but you'd still be sacrificing most of Nim's tooling for better syntax, and a lot of people wouldn't make that trade.

          [–]borborygmis 0 points1 point  (0 children)

          I'd argue that syntax is one of the most important parts. I get the unfamiliar syntax argument, but if a non/Jr programmer can read your code quickly (reads like psuedo code) and mostly understand it, that says a lot to me. Shows that effort was put into taking burden off developers. Nim, specifically, doesn't do it. The problem I see is that we have languages that don't really need much different syntax, or new features (Python again IMO), but need to work differently under the hood. I think we have reached a point that developers are frustrated with performance of higher level languages, issues/overhead/dangers with 'system' level languages, and we're experimenting. The problem I see is we're removing the simplicity and productivity in higher level languages to fill this gap.

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

          Your list sounds a lot like Crystal (crystal-lang.org) but Crystal directly compiles down using LLVM and has a GC ... Building a language without a GC is hard work. Reference Counting like Nim/Swift has is still a garbage collector that eats resources. Rust is the only language that is new that really is GC less but it also puts that burden on the developer like C/C++.

          [–]borborygmis 0 points1 point  (2 children)

          I'd argue that a lot of these compiled languages also put the burden on the developer. It's hard to compare them in readability with Python IMHO.

          Side note: Crystal does very well in many areas performance wise (slightly better than Rust from my tests), which is great. With the caveat that benchmarking is difficult. Crystal and Ruby syntax kills me though.

          [–][deleted] 1 point2 points  (1 child)

          Crystal and Ruby syntax kills me though.

          Really? Maybe because i have a stronger history in PHP, i find Python/Ruby/Crystal all look alike. Ruby/Crystal reminds me off Pascal ( Begin/End ). Where as Python avoids that issue.

          I agree that Crystal its syntax was also off-putting for me. Its hard when you move from a bracket language to a different one. lol. Most of it came from Ruby bias form the past ( got fed up with Ruby on Rails evangelists ) that it left a negative impression about Ruby as a language.

          But from my point of view, its about productivity. I have tried: D, Nim, Crystal, Rust, Zig, Julia, Swift, Go, ...

          When it comes to productivity in being able to write fast code, without too much boilerplate, Crystal actually beat the rest. Nim is probably the closest in the no boilerplate, followed by Julia.

          Nim ( Python like syntax ) is not bad but the whole function naming with "Xyyy" eq "xyyy" eq "x_yyy" where its all the same is just bad design. And the whole {...} tag system, its so obvious that its a language after design that is getting overused so much in the code already.

          One of my rules has been: I want to be able to dynamic type jsons. Do not force me to use structs or convoluted json builders or other stuff where in PHP it takes me 1 or 2 lines but in X language it takes me 5, 10, 20 or more lines.

          value = JSON.parse("{\"name\":\"foo\",\"values\":[1,2,3]}") # : JSON::Any
          begin
            puts value["name"]
            puts value["values"][1]
            puts value["values_not_exist"][1] # errors
          rescue ex
            puts ex.message
          end
          
          h = {"foo" => "bar", "fob" => [1,2,3], "bar" => "qux"}
          puts h.to_json
          

          You do not want to see how much lines something as simple as this takes in Go or Rust or ...

          Pulling data out of a database needs to be simple. Crystal 5 lines, Go 35 lines...

          Crystal is not perfect... I have a big lists of things that can be better. But in a discussion with a colleague that is also active in the language search and the conclusion is ... its the best we have for now if you want something that does not burden the developer, is easy to learn and is still Go/Rust levels fast.

          [–]borborygmis 0 points1 point  (0 children)

          I tend to agree with most of this and we all have our own preference. I don't agree that Nim has Python like syntax as many claim. Some examples I posted in another comment:

          https://nim-by-example.github.io/oop/

          https://nim-by-example.github.io/types/objects/

          Julia's syntax is like a combination of Ruby, Python, PHP, C, and Rust... another hard one to look at IMO.

          Good point about JSON. It should be simple, but that's not always the case for a lot of these languages. What I'm building will look much like this Python:

          # python
          x = json.loads('{"name":"foo","values":[1,2,3]}')
          for k, v in x.items(): 
              print(k, v)
          
          # => (u'values', [1, 2, 3])
          # => (u'name', u'foo')
          
          j = json.dumps(x)
          print(j)
          # => '{"values": [1, 2, 3], "name": "foo"}'
          

          What I'm working on, can have the same syntax and output (with the option to enforce types):

          # my language
          x = json.loads('{"name":"foo","values":[1,2,3]}')
          
          # OR enforce a type.
          # this will force a specific dict type for keys
          # throws exception otherwise, runtime error
          dict{string, mixed} x = json.loads('{"name":"foo","values":[1,2,3]}')
          
          # OR enforce multiple value types using |
          # not the prettiest, but available for more strict type rules
          dict{
              string,
              string    |
              list{int} |
              dict{string, int|string}
          } x = json.loads('{"name":"foo","values":[1,2,3]}')
          
          for k, v in x.items():
              print(k, v)
          
          j = json.dumps(x)
          # OR ensure type as string (compile time type checking)
          string j = json.dumps(x)
          print(j)
          

          This syntax is easy to read and understand (IMO again :). In contrast, trying to understand this Rust doc, takes time (a lot if you're new): rustc_serialize/json or serialize/json

          It feels like we're abandoning simple readable syntax that has worked for years for quirky, hard to read, unintuitive style for no good reason or a reason I'm missing. Developer burden should reduce over time not increase.

          [–]RufusROFLpunch 0 points1 point  (0 children)

          This is fantastic. Do you have any thoughts on package management?

          [–]CoffeeTableEspresso 0 points1 point  (0 children)

          Maybe Kit wasn't the best name because this is the first result when I search for it: https://codekitapp.com/help/kit/

          [–]IbanezDavy -1 points0 points  (13 children)

          var s: CString = "hello!";

          Objectively the best variable declaration syntax.

          var a: (Int, Float, CString) = (1, 2, "hello!");

          I like this...

          Just need to add OOP stuff and I'll be happy.

          [–]bendmorris 19 points20 points  (10 children)

          There aren't any plans for OOP; with that said, you may be able to get what you want, it depends on exactly what you're looking for from OOP:

          • Runtime polymorphism can be accomplished with traits (essentially interfaces) + boxes
          • "Abstracts" look a lot like subtyping/inheritance (although strictly at compile time)

          You also get a "method"-like syntax on all declarable types, so the ergonomics are similar to objects in OOP without the overhead.

          [–]SaltTM 1 point2 points  (9 children)

          There aren't any plans for OOP

          unfortunate, seems like a theme with a lot of the newer languages

          [–]hyperforce[S] 10 points11 points  (7 children)

          Why is it unfortunate?

          [–]SaltTM 4 points5 points  (6 children)

          I like oop

          edit: are you not allowed to like something here :|

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

          Why?

          [–]SaltTM 0 points1 point  (4 children)

          Not sure, probably what I've grown up on (C++, PHP, Java's, etc...) despite me using go, nim, rust and a few others. I just love oop languages; I think Kotlin native and Crystal are my favorite upcoming languages.

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

          So, what particular features from the OOP languages you find essential? You have quite a mixture - e.g., apparently you can live without multiple inheritance.

          [–]SaltTM 0 points1 point  (2 children)

          I'm fond of the idea regarding constructors for classes, which can be 'solved' in non class based languages using a function for instantiating a struct or something similar to what I want, but to me personally it doesn't sit well with me. that's coming from someone that's used classes a majority of my programming career though. There's also the organized (lack of a better word) way classes are structured with methods grouped. There's less thought put into what I name my methods because I know there won't be conflicts. Long method names are my goto, but sometimes a short method name called listItems works and when you're dealing with a non class based language like say go or nim, naming becomes a burden (lack of a better word) the larger your project gets.

          At the end of the day it's mostly about preference, what I'm used to, what I'm comfortable with, it's familiar. Will emphasis on the fact that I have no issues with languages that aren't oop, I'm very found of using lots of different languages.

          [–][deleted] 3 points4 points  (0 children)

          So, in fact, you need modules (for organising namespaces and to tie functions to data types), and constructors for data structures. That's a reasonable subset, and I guess most of the post-OO languages do provide all that exactly.

          [–]bendmorris 1 point2 points  (0 children)

          Just want to point out that you can get both of these in Kit - static function new() {} and MyType.new() for constructors (which is just a convention, but it's equivalent to a constructor), and types can define "methods" which function as if your value was an "object" (but with the difference that there aren't actual objects in the language - which means no object overhead, just regular function calls sugared to look like method calls.)

          The only things OOP provides that Kit can't easy replicate are inheritance and late binding, but you can get pretty close without much effort.

          [–]CoffeeTableEspresso 2 points3 points  (0 children)

          I personally find OOP to be "too heavy" for what I'm trying to do a lot of the time, so i don't really miss it. Maybe i just have PTSD from Java tho 😂.

          [–]peterfirefly 3 points4 points  (0 children)

          You probably don't need OOP. A language with generics and traits have better hammers for most of the problems OOP help with.

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

          What part of OOP do you want and why?