Settings

Theme

Little is a statically typed, C-like scripting language

little-lang.org

192 points by Thedarkb 5 years ago · 133 comments

Reader

asicsp 5 years ago

http://www.little-lang.org/why.html is pretty interesting

>We (BitKeeper folks) did our GUI interfaces in Tcl/Tk years ago because it meant we could have one gui person and get the same gui tools on Windows, Mac, Unix, and Linux.

>While some of us could switch from C to Tcl easily, our pointy-haired boss could not, he's mostly C and would lose about a half a day to get back into Tcl.

>Success was realized when one of our engineers, who is not a Little fan, fixed a bug in a patch that flew by in email without realizing it was Little instead of C

luckydude 5 years ago

Wow, just noticed this. I'm the guy who paid for Little, a bunch of other people did all the work.

I'm surprised to see it getting some attention but happily so. Little is what I'd like C to evolve towards, there is a lot of useful (to me) stuff in the language.

I'll wander through the comments and reply where I can.

  • luckydude 5 years ago

    I just realized I didn't give credit to all the people who worked on Little. So here goes. Tim Daly did the first pass. Oscar Bonilla stepped up, I still remember him saying to Tim "we need an AST" and Tim said I can do this. We needed an AST, Oscar was right about that and a lot of other things. Rob Netzer, my roommate from college and former Brown tenured prof, he did the most heavy lifting in the Little compiler. Damon Courtney was our GUI guy, he had huge influence in Little.

    Jeff Hobbs from the tcl community helped as well. I have pictures of that group of people. Jeff helped a lot, he wanted this, I could say why but I don't want to speak for him.

    Little is what I'd like C to be but those guys made it happen.

    I'm amazed that Little got some traction, happy that it did for a moment, those guys deserve all the credit, I was a whiny dude wanted a more C like thing and they gave it to me.

  • marktangotango 5 years ago

    I'm curious if you've written about the decisions around licensing that essentially killed the bitkeeper business by inspiring Linus to create git? What are your thoughts around that today?

    • luckydude 5 years ago

      Hind sight is 20-20. The BitKeeper business had a good run, we were around for 18 years. It made enough that I and my business guy are retired off of what we made.

      On the other hand, we didn't make enough for everyone to retire if they wanted to. We had a github like offering and it's pretty clear that we should have put a bunch of money into that and open sourced BitKeeper.

      All I can say is it is incredibly hard to make that choice when you have something that is paying the bills. I tried to get Sun to do it with the BSD based SunOS and they wouldn't. And even though I had that vision for Sun, when it was my livelihood, I couldn't see the path to doing so.

      Shoulda, coulda, woulda, my biggest regret is not money, it is that Git is such an awful excuse for an SCM. It drives me nuts that the model is a tarball server. Even Linus has admitted to me that it's a crappy design. It does what he wants, but what he wants is not what the world should want.

      It says a lot that we have a bk fast-export and we can incrementally run that and get idempotent results. As in go from BK to Git on an ongoing basis, have two people do it in parallel and they both get bit for bit identical results. If you try and go the other way, Git -> BK, if you do it in parallel you get different results because Git doesn't store enough information, so BK has to make up the missing bits.

      Git has no file create|delete|rename history, it just guesses. That's my biggest regret, I wish Linus had copied that part.

      • JNRowe 5 years ago

        Now that all that isn't so raw, I'd love to know how you felt about the other contenders that were floating about at the time. Were any of them doing things you wanted to see in BK?

        I can't be the only one who'd be interested in your views on the general developments for such important tools of our trade. Have you written about it anywhere? I'll pre-order "Larry walks us from SCCS to the git monoculture".

        • luckydude 5 years ago

          Actually I was part of an SCM conference put together by Facebook and Google recently. People are starting to think about what happens after Git.

          Unfortunately, even now, it seems that there is a lot catching up to BK still to be done. To be fair, we had kernel level programmers working on it, we don't think anyone will pick up our code, you pretty much have to be a top 1-2% programmer to work on it, it's all in very disciplined C, people don't seem to like that any more.

          So far as I know, BK is the only system that gets files right, we have a graph per file, everyone else has a single graph per repository. The problem with that is the repository GCA may be miles away from the file GCA; BK gets that 100% right, other systems guess at the GCA. Graph per file means each file has a unique identifier, like an inode in the kernel. So create/delete/renames are actually recorded instead of being guessed at. SCM systems shouldn't guess in my opinion (actually in anyone with a clue's opinion, would you like it if your bank guessed about your balance? Of course not, so why is guessing OK in an SCM? It's not). Graph per file means that bk blame is instant no matter how much history you have.

          BK is the only system that even attempts to get sub-modules (we call them components) right. Where by "right" I mean you can have a partially populated collection and you get identical semantics from the same commands whether it is a mono-repo or a collection of repos. Nobody else has anything close, Git sub-modules turn Gits workflow into CVS workflow (no sideways pulls).

          I tried my best to show what we did in BK at that conference, I have no idea if they will swipe any of it. It's not like BK is perfect, it didn't do everything, no named branches, a clone is a branch, which is a model that absolutely will not scale to what people are doing today (we can argue whether TB repos should exist, but they do).

          But for the problems BK did solve, it tended to solve them very well. Hell, just our regression tests are a treasure trove of things that can go wrong in the wild and we open sourced both the tests and the test harness.

          • JNRowe 5 years ago

            Thanks, although I think you're demonstrating here and in the other comments why you should write a real history.

            Was the conference recorded? I've tried searching, but I'm not turning anything up.

            As an outsider you get my worthless full agreement on strictness of history, and on solving the monorepo or vendoring dilemmas. My employer at the time of the upheaval was a bitmover customer, and as we slowly switched away one repo at a time it definitely felt like a sideways step. I'd hesitate to say backwards because it did come with some big process improvements for us, but definitely not forwards.

            I'd surely have been proud of solving problems with the quality that BK did too. I remember playing with a lot of the open source systems of the time¹, and none of them were in the same league. I'll make no apologies for this sounding like truly weird fan mail.

            ¹ I'm remembering hg, darcs, monotone, $some_implementation_of_arch, prcs, codeville but there was a lot of people in the space to some degree.

            • luckydude 5 years ago

              I think it was recorded, I'll go look.

              Apologize for saying BK is quality? None needed, we prided ourselves on producing a quality product. And great support, our average response time, 24x7, was 24 minutes. It was only that "slow" because we were North America based. If you only considered the US work week, response time was usually under 2 minutes, but that's not reasonable because we had customers all over the world.

              I'm gonna start with a write up of the SCCS weave, with a goal that it is enough of a spec that you could go implement it. Maybe add some notes about how I did it because the way I did it was unusual and had the side benefit that you could extract the GCA, left tip, and right tip for a merge in one pass.

          • nextaccountic 5 years ago

            What do you think about patch-based systems like Darcs and Pijul instead of snapshot-based systems like Git?

            Recent article on Pijul: https://initialcommit.com/blog/pijul-version-control-system/

            • luckydude 5 years ago

              I think if you are asking this question either I have completely failed to explain why weaves are cool or you haven't read what I said about why weaves are cool.

              Patch based systems are idiotic, that's RCS, that is decades old technology that we know sucks (I've had a cocktail, it's 5pm, so salt away).

              Do you understand the difference between pass by reference and pass by value? You must, but in case you don't, you can pass by reference in sizeof(void *), 4-8 bytes. Pass by value and you are copying sizeof(whatever it is you are passing) onto the stack. Obviously, pass by reference is immensely faster.

              But in SCM, it isn't just about speed (and space), it's about authorship. In a patch based systems, imagine that there is user A who is doing all the work on the trunk, there is user B who is doing all the work on a branch, and then there is user U who is merging the branch to the trunk. Lets say B added a bunch of work on the branch, it all automerged. U did the merge. In a patch based system, all of the B work is going to be copied (passed by value) to the trunk and the authorship of that work will change from B to U (since U did the merge).

              Flip forward to a month from now, the code has paniced or asserted, whatever, B's code on the trunk took a crap. And people are running git blame to see who did that and who did it, U did. But U didn't, B did but U merged it and it was a copy so it looks like U did it.

              That's just the SCM being dishonest because it has no choice, it is pass by value.

              Weaves are pass by reference. If you merged in BitKeeper and it automerged, you run blame (we call it annotate but I should make blame be an alias if I haven't already, I'm the guy that came up with blame as that verb), you would only see A and B as the authors.

              Weaves mean authorship is correct and that whole repack nonsense that Git does? Yeah, that goes away, you are passing every thing by reference so there is only one copy of the code no matter how many branches it has been merged from/to.

              Anyone who is pushing a patch based system (and Git is one as well) just doesn't have a clue about how to do source management. Maybe something better than a weave will come along (and if it does, rbsmith will do it, that guy bug fixed my crappy weave implementation) but I think it will just be a better weave with new operators like MOVE (current weaves know INSERT and DELETE, that's it).

              Sorry if I'm being a dick, not looking for sympathy but I've got health problems, my feet hurt like crazy and I get kind of terse at the end of the day. If you truly want to understand more, and this goes for all of hacker news, I'm happy to get on a zoom call and talk this stuff through. And it is blindingly obvious I need to write up the SCCS weave and I will do so, you guys have inspired this 58 year old, burned out, can't code to save his life, dude to at least try and pass on some knowledge. I would love to be working with some young person who has some juice and pass on what I know. I don't know everything about SCM but I know a lot. I'm done, it's time for someone else to carry things forward, I'll help if you want. The world deserves a better answer than what we have now.

              • neolog 5 years ago

                I'd be interested to see a conversation between you and the Pijul author. He hangs out in the forum at https://discourse.pijul.org/ and the chat at https://pijul.zulipchat.com/.

                • pmeunier 5 years ago

                  Turns out I also hang out here sometimes ;-)

                  I was about to reply point by point with arguments, but I changed my mind:

                  I don't think I'd be interested in that conversation, the comment above is worse than a public display of a very poor understanding of Git and Pijul: it also shows a complete ignorance of other actors in the market. It turns out the market leader for big repositories, Perforce, is itself based on RCS, possibly (but I don't know for sure, since Perforce is proprietary) because RCS scales much better to large binary assets than other solutions (I'd argue Pijul solves that, but that's beside my point).

                  I am a big fan of Git, Mercurial and Darcs myself, my co-author on Pijul was actually a maintainer of Darcs for many years, and I'm actively collaborating with the maintainers of Mercurial at the moment. And even though Perforce and Plastic are closed-source, they do solve one problem (scalability) which distributed systems are only beginning to understand (if there's one thing I think we've achieved with Pijul, it is about getting beyond the "distributed vs. scalable" trade-off).

                  Here's my take on the comment above: I don't think you can build good systems without understanding how others are made. There are no free lunches, no silver bullets, no geniuses. Only good ideas, bibliography, and hard work.

                  • luckydude 5 years ago

                    I've built two commercially successful systems, NSElite that was used to develop the Solaris kernel and was productized as Avocet/CodeManager/TeamWare (don't blame me, I didn't name it), and BitKeeper which was, at one point, in use on every continent other than the Arctic. If you are running on a 5 year old Intel CPU, that was developed using BitKeeper.

                    The comment that RCS scales for binaries couldn't be more wrong, RCS hates binaries with a passion.

                    The fact that you didn't address any of the points I raised says you either don't understand what a weave file format is, or, you do, you recognize it is a much better format but don't want to talk about that.

                    This part of this thread reminds of something Ron Minnich once said: "Don't worry about people stealing your ideas, you are going to have to cram them down their throats".

                    I'll drop it, we can revisit when I write up how weaves work. I don't think any objective person would argue that a patch based system is as good, let alone better.

                    • pmeunier 5 years ago

                      I came back here to say:

                      > I've built two commercially successful systems,

                      This is a great achievements, congrats on that!

                      All I was saying in my previous comment was, these very cool achievements don't prevent you from calling all other people "idiotic", and from saying "they don't have a clue" without even looking at their designs, or even thinking that they might have had ideas different from yours.

                      Also, calling Git "patch-based" is quite wrong, but my point wasn't technical.

                    • pmeunier 5 years ago

                      > The comment that RCS scales for binaries couldn't be more wrong, RCS hates binaries with a passion.

                      That isn't what I meant, I was actually talking about Perforce. RCS doesn't even handle multiple files.

                    • neolog 5 years ago

                      Tbh I think it's not likely to be a productive conversation if unless insinuations of bias and ignorance can be eliminated.

                      • luckydude 5 years ago

                        I think the most productive thing I could do is write up how the weave works. People don't seem to understand that, if they did, nobody would be talking about patches.

                        I'm sorry if I pissed off the other guy, but I'm retired, and I'm tired, and I have no interest in arguing with people who don't get it. But it's on me to provide the info that lets them get it. I'll do that and what people do with it is up to them.

                • pmeunier 5 years ago

                  (Also, our Discourse and Zulip have been pretty civil places until now, I'd like to keep it that way).

          • ymbeld 5 years ago

            > Unfortunately, even now, it seems that there is a lot catching up to BK still to be done. To be fair, we had kernel level programmers working on it, we don't think anyone will pick up our code, you pretty much have to be a top 1-2% programmer to work on it, it's all in very disciplined C, people don't seem to like that any more.

            Oh my oh my.

            • luckydude 5 years ago

              Believe me, I would do backflips if someone wanted the BK source base, it's got almost 2 decades of my work in it, north of 140 man years. It's a lot to just let fade away.

              But I assembled a team of people better and smarter than me, I did my best to keep the code simple but I didn't always succeed.

              If you, or anyone, wants to pick it up, I'm happy to answer questions.

              • mucholove 5 years ago

                Will take a look at it.

                At this point, the trick to creating a sizable git alternative I think is to Trojan horse coding into a new realm with “no-code” like apps.

                One of my favorites is Fossil by Richard Hipp. I wonder what your thoughts on it are. I think it is RCS, but usability wise I think it’s way ahead of git.

                I just recently learned C and I really like the coding style Hipp uses as well. :)

                • luckydude 5 years ago

                  Richard is awesome. He also did sqlite. As for Fossil, I'm a fan of his UI and code, but haven't looked in detail at the design. I'm pretty sure it is patch based with everything stored in sqlite. It's an OK way of doing things but not if you understand a weave.

                  But no disrespect intended towards Richard, I've met him plenty of times and enjoyed it each time. Great guy.

      • temporallobe 5 years ago

        I know Git quite well at this point in my career, but it’s still a very baffling and often frustrating SCM tool in my opinion. I find it disconcerting that despite many years with it, I still feel like I don’t totally comprehend what really is happening under the hood. There seems to be a lot of magic. I still have a sense of apprehension every time I do a rebase, and after successful conflict resolution I am surprised that it somehow worked given how messy and convoluted the rebase workflow is.

        One of the oddest things I more recently learned about Git is that you can’t create empty folders. The workaround is to create an empty file (e.g., a README)!

        That being said, entire careers are built on this powerful yet odd tool that has somehow become the most popular SCM system in the world.

        • scruple 5 years ago

          > One of the oddest things I more recently learned about Git is that you can’t create empty folders. The workaround is to create an empty file (e.g., a README)!

          The convention I've seen is `.keep` and `.gitkeep`.

      • hyperpallium2 5 years ago

        I so appreciate you answering questions here!

        I've experienced how Git's lack of file rename makes it hard to follow changes through directory and file reorganization. This made me reluctant to reorganize, as I learned the problem space. The general, long-term impact may be increased ossification pressure.

        OTOH linus's content addressable system is absurdly, compellingly simple, and does 90%. It's disproportionately simple. A dilemma!

        BTW I think many companies get killed that way. Refusing revenue to profit must be pollyanna - except for github. OTOH keeping customers is how great companies get killed, according to Christensen (the innovator's dilemma).

      • brundolf 5 years ago

        I hadn't heard of BitKeeper but it sounds interesting. Have you considered open-sourcing it now for people to look at, even though the business has faded?

    • luckydude 5 years ago

      BTW, Linus switched to Git 2005. BitKeeper didn't give up and turn to open source until 2016. So we had a 10 year run after Git showed up where people still paid us.

      It was good run, not many software companies get an 18 year run. I'm fine with it, would have liked to do more for my people.

      Though, when we were shutting things down and I was bumming that I had not gotten retirement money for all of my people, one of them said something like "Dude, are you kidding me? My best friend barely knows his kids, he is out the door by 7am to fight Houston traffic and not home until close to 7pm. My commute is from my bedroom to my office down the hall. I've got to help my wife with the kids, I see the kids all day every day, my life is infinitely better than my friend's life and you gave that to me. You're fine."

      I'm a wimp, I teared up a bit, that was the nicest thing he ever said to me. It's not just about money.

  • rdpintqogeogsaa 5 years ago

    I just wanted to say thank you for believing in the SCCS weave when making BitKeeper. It is an incredibly elegant design (though I've failed to properly implement it myself yet).

    • luckydude 5 years ago

      The SCCS weave was our secret sauce. Tichy did the world a huge disservice in his PhD about RCS (like that was worth a PhD, come on) where he bad mouthed SCCS's weave (without understanding it, or maybe he was spreading misinformation on purpose, he implied that SCCS was forward deltas where RCS is backwards deltas, see below for what that means).

      When we were still in business, each new SCM that came out, we'd hold our breath until we looked at it and said "No weave!"

      For those who don't know, the SCCS weave is how your data is stored. Most people are used to something like RCS which is patch based. For the RCS trunk, the head is stored as plain text, the previous delta is a reverse patch against the head, lather, rinse, repeat. Branches are forward deltas, so if you want to get something on a branch, you start with the head, apply reverse deltas until you get to the branch point and then forward deltas until you get to the branch tip. Ask Dave Miller how much he loved working on a branch of gcc, spoiler, he hated it. With good reason.

      SCCS has a weave that is not aware of branches at all, it only knows about deltas. So you can get 1.1 in exactly the same amount of time as it takes to get head, it is one read through all the data. bk annotate (git blame) is astonishingly fast.

      And merges are by reference, no data is copied across a merge. Try that in a patch based system. How many of you have been burned because you merged in a branch full of code that someone else wrote, and on the trunk all the new data from the branch looks like you wrote it, so you get blamed when there is a bug in that code? That's because your brain dead system copied code from the branch to the trunk (Git does this as well, that's what the repack code is trying to "fix", it is deduping the copies).

      Weaves are the schnizzle, any SCM system that doesn't use them today is so 1980.

      • froh 5 years ago

        How does dcfs weave compare or relate to what pijul.org is doing?

        Some recent discussion of pijul on HN:

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

        • luckydude 5 years ago

          It's based on patches. I'm perhaps not going to win any friends, but I think that is ill-advised. Patches are great for emailing around, they are a horrible idea for an SCM.

          Perhaps I need to write up how weaves work in more detail. Once you get that, you won't want an SCM based on anything else.

  • amacbride 5 years ago

    Avocet (CodeManager) ruined me for other source control systems for years and years — I still look back on it fondly.

    • luckydude 5 years ago

      That was me as well, though I wrote it in perl4 and C. My version was called NSElite. The Solaris kernel was developed under NSElite, some stuff is here:

      http://mcvoy.com/lm/nselite

      2000.txt documents the first 2000 resyncs (think bk pull) of the kernel.

      Avocet was what you got when you took all my perl code and handed it to the tools group and they rewrote it in C++ (which they later admitted was a horrible idea). The only thing of mine that they kept was smoosh.c and that was because not a single one of them had the chops to write that code (yeah, there was no love lost between me and the tools group).

      BitKeeper is what Avocet could have been if Sun had not stopped me from doing any more work on NSElite (I was 1 guy who was coding circles around 8 tools people and they didn't like it). Shrug. C++ was just wrong, perl4 was just way faster to code in, and when I needed performance I coded in C. It's not my fault they picked the wrong way to go about things. (That, BTW, was the first time I ever personally saw that you really can have one guy who can do the work of 8, almost, but not quite a 10x programmer :-)

fuball63 5 years ago

Not to be confuse with lil, which is a small scripting language based on TCL: http://runtimeterror.com/tech/lil/

I think this is a super interesting project. It reminds me what Groovy is to Java, but backwards. Groovy is a “looser” version of Java that compiles Java. Little is a “stricter” version of TCL that compiles TCL.

  • narrator 5 years ago

    TCL had some bad features that kind of killed it. For example, "upvar" was a really bad idea. Bad features tend to kill languages over time. Everyone used to use Perl in the late 90s. It had too many bad features though, and nobody wanted to maintain those programs.

    • derefr 5 years ago

      I've always been surprised that nobody has tried to take a "The Good Parts" subset of a big language (C++, Perl, etc.), codified/formalized it as its own language, and then attempted to popularize the new reduced language as a distinct effort/project/community to that of the original language.

      One could release this "language" as a distribution of the inner language's compiler together with a wrapper (like C++ originally was to C), that, rather than adding features and compiling down, just analyzes the source file and errors out on use of forbidden syntax; or, if no forbidden syntax is used, just passes your code straight through to the inner compiler. A bit like a pre-commit-hook style checker, but a pre-compile-hook style checker.

      • TimWillebrands 5 years ago

        For c++ there is orthodox c++ which is a subset of the larger language. Although as far as I know there is no linter/compiler. https://gist.github.com/bkaradzic/2e39896bc7d8c34e042b

      • luckydude 5 years ago

        I just liked what is in Little, it's enough like C that it is trivial for me to jump into it (tcl always took a half a day, I really dislike the tcl syntax), it's got enough of the shortcuts from perl that it is pretty terse, and credit where credit is due, syntax aside, tcl has a bunch of useful stuff, check out Little's switch(), that's tcl's switch.

      • forgotmypw17 5 years ago

        I have not tried to codify it yet, I think mainly because I'm still figuring it out, but I've been doing this with Perl and PHP, writing in a lowest-common-denominator style which is almost identical between the two...

      • prirun 5 years ago

        Someone should do this with Nim.

    • nrclark 5 years ago

      I always thought upvar was kind of a cool feature, and allowed laser-specific targeting in places where you'd use a global otherwise in C. Is there any specific way that it's caused problems?

      • fuball63 5 years ago

        I like it too because it's DIY pass by reference.

        • luckydude 5 years ago

          We obviously liked it because upvar is how Little passes by reference. I don't know why someone thought upvar was bad, it is useful.

    • isr 5 years ago

      Hmm, I would disagree with this (quite strongly). Not that tcl doesn't have misfeatures (of course it does), but that `upvar` or `uplevel` are one of them.

      Those commands effectively make any tcl function be able to operate as an f-expr (in old lisp parlance). Effectively (this is a simplification), an fexpr is a runtime macro, as opposed to the more traditional lispy compiletime macro.

      Its what makes tcl feel more like a lisp-for-strings. Much of the truly horrible tcl code out there in the wild is from folks who try to use tcl as just another c-style scripting language.

      Treat it more as a lisp, and it some of its inherent elegance shines through.

      My $0.02 anyway ...

      • kazinator 5 years ago

        Fexprs are misfeature, which is why we have to digging into sixty-year-old Lisp literature to learn about them.

        Lisp people had bad ideas along the way. They recognized that this is the case and got rid of those ideas, in some cases documenting some of those choices.

      • luckydude 5 years ago

        I sort of agree with this. I'm not a lisp fan, I don't think lisp is bad, it's just not how my brain works so I struggle. But I understand lisp enough to agree with you and I think that is what John was trying to do.

    • csande17 5 years ago

      What's upvar?

      • luckydude 5 years ago

        http://www.tcl.tk/man/tcl8.5/TclCmd/upvar.htm

        That man page isn't the most clear. upvar gives you a way to modify a variable in the calling context (and I think it can go up more than one stack frame).

        It's a way to pass by reference rather than the default pass by value (how tcl passes is more complicated than that for performance but the default semantics are pass by value).

      • kazinator 5 years ago

        upvar means that you have access to the variables of the calling function. You can ask, what is the value of local variable foo in the scope that is calling here?

        It's a facepalm-stupid thing to put into a programming language. Programs that use it will not be efficently compilable; the compiled code will have to provide upvar access similarly in order to make them work.

        When compiling a function, you don't know which callee might ask for an upvar, so you can't optimize away variables or keep them in registers across calls.

      • nrclark 5 years ago

        Not much, what's up with you?

BruceEel 5 years ago

   Compiles to Tcl byte codes
Interesting, I didn't even know there was such a thing. Good to see <> and =~ live on.
  • simias 5 years ago

    =~ is nice and convenient but I really don't think <> was worth bringing back. I'm sure people who never used Perl could figure out what `buf =~ /${regexp}/` does, but I wonder if they'd be able to figure out the `while (buf = <>)`.

    Perl has a lot of good ideas and things I find myself missing a lot when I use Python or JS (autovivification being probably #1) but IMO these one or two symbol magic variables would generally be improved if they were more descriptive, with maybe one exception for $_/@_.

    Although I must admit reminiscing about this made me realize how much I miss Perl now that I'm forced to use Python for work.

    • jiofih 5 years ago

      Autovivification was one of the most painful features I’ve had to live with - in a large codebase it completely erases trust on any kind of defined() check and breaks all sorts of things unexpectedly.

      Yet another horrible hack in Perl that for some reason is advocated for. Optional chaining / null propagation is a much, much better idea and shouldn’t have been any harder to implement.

      • simias 5 years ago

        I see how that can become a problem but I think the pros outweigh the cons. Maybe the problem is because of a "very large" codebase, my general hot take is that dynamic languages like Perl and Python should be used primarily for scripts. The lack of static typing makes dealing with very large codebases rather painful in any case, in my experience.

        Null propagation is nice too, but it doesn't address all the uses cases of autovivification when you have, say, a hash table of arrays and you want to insert a new entry in an array, creating it if it doesn't exist. In python you have to use setdefault which I always found clunky.

      • lizmat 5 years ago

        FWIW, that was one of the things that Larry fixed in Perl 6 (now the Raku Programming Language https://raku.org #rakulang).

        You can bind to a non-existing hash element (even multiple levels deep) and it won't exist until you actually assign to it:

            my %h;
            my $c := %h<a><b><c>;
            say %h<a>:exists;  # False
            $c = 42;
            say %h<a>:exists;  # True
    • luckydude 5 years ago

      I wrote most of my first source management system (NSElite, mentioned elsewhere in this thread) in perl4. I was learning perl at the time and my first and second efforts were awful. Perl really lets you get sloppy and create unmaintainable code.

      My 3rd rewrite was very stylized and, I felt, maintainable. Which proved to be true as I had to fix bugs in it.

      I did weird stuff like using $whatever as the index into the @whatever array.

      But I digress. On the <>, Little has argv so you can do

      int main(string argv[]) { int i; string buf; FILE f;

          if (defined(argv[1]) && streq(argv[1], "-") && !defined(argv[2])) {
              while (buf = <STDIN>) bputs(buf);
          } else {
              for (i = 1; defined(argv[i]); i++) {
                  if (defined(f = fopen(argv[i], "r")) {
                      while (buf = <f>) puts(buf);
                      fclose(f);
                  } else {
                       fprintf(stderr, "unable to open '%s'\n", argv[i]);
                  }
              }
          }
          return (0);
      }

      but why would you want to when all of that is

      int main(string argv[]) { string buf;

          while (buf = <>) puts(buf);
          return (0);
      }

      I mean, come on, that's cat(1) in 8 lines of code.

      edit: I need to learn hacker markup. My code looks like crap.

      • hyperpallium2 5 years ago

        It's indent by two spaces. Guessing your style:

          int main(string argv[]) { string buf;
            while (buf = <>) puts(buf);
            return (0);
          }
    • tyingq 5 years ago

      I do find <> helpful. Perhaps if it were more descriptive? <ARGVorSTDIN> or similar?

      • derefr 5 years ago

        In Ruby it's called ARGF (https://ruby-doc.org/core-2.7.1/ARGF.html) — which, if not perfectly descriptive, is at least evocatively similar to ARGV.

        If you're already aware that ARGV exists, you'll guess that ARGF might be used in relation to it, and so when writing a CLI program that uses ARGV, you might wonder if ARGF could simplify your code and look up what it is/does.

      • simias 5 years ago

        Yeah to be clear it's not the functionality that bothers me, it's just the syntax. Ideally since it's not even a proper variable since it changes after reading it should probably look like a function call.

        These ultra terse shorthands make some sense in the shell because it's meant for interactive, write-only commands but a scripting language should be a little more verbose and consistent IMO.

        • luckydude 5 years ago

          I'm a huge fan of preserving knowledge and building on it. Most people, at the time at least, knew what

          while (buf = <>)

          did. So I didn't want to invent a new syntax, there is way too much of that going on, I like C, I like perl, pull the useful stuff from each and move on.

          I freely admit it's not how everyone would do it.

        • Spivak 5 years ago

          There’s a balance because people really seem to like ? as null coalescing, => for lambdas =~ for regex match, etc..

          I think <> as a fancy readline and _ as a default/throwaway variable does really improve readability and lowers the mental load of understanding programs.

nightowl_games 5 years ago

Curious on performance benchmarks. For me, I'm comparing this to wren:

https://wren.io/

  • luckydude 5 years ago

    There are some benchmarks here:

    http://mcvoy.com/lm/L/tcl/tests/langbench/

    some results in the README. Perl holds up well. These are probably 10 years old though.

  • tyingq 5 years ago

    Tcl is historically very slow. Especially for synthetic CPU intensive benchmarks. However, since it's so easy to interop with C, it didn't seem to matter much in the real world. You just put anything performance sensitive in C and left the bits that didn't matter in tcl. Some benchmarks: https://github.com/trizen/language-benchmarks

    • ThedarkbOP 5 years ago

      It takes Little 3.53 seconds to find the 33rd number in the Fibonacci sequence recursively versus 30.23 seconds for Tcl8.6 on my i5-3320M.

    • rkeene2 5 years ago

      Additionally, you can compile Tcl to machine code with TclQuadCode for up to a 66x speed improvement

Tade0 5 years ago

I originally read it as "Life is..." and thought "that's an interesting take on things".

  • slazaro 5 years ago

    Make it a T-shirt, the fake-deep tone for a nonsensical statement is kind of ironic/cool.

    • Tade0 5 years ago

      I think there's a very real possibility that trying to do that I would dissolve from the embarrassment like the witch in The Wizard of Oz.

0xbadcafebee 5 years ago

Why are there so many different languages that are almost the same except for one or two attributes? Why not make one language that can do everything?

If you can make one language strongly typed, and one weakly typed, then you should be able to build one language which can do either/or, depending on a compiler flag. Then you simply decide before you start writing your code whether you want to write it weakly typed or strongly typed, and pass the correct compiler option.

Take that same idea, but add in every language's quirks, and just enable/disable them. Then we wouldn't need to constantly reinvent languages, because we'd have one that can do everything.

Otherwise we're going to keep re-writing the same damn thing for hundreds of years, and that just seems like such a pointless waste of effort.

tyingq 5 years ago

The repo is odd, it's hard to tell where the actual little-lang code is. I guess it's in the tclXXX directory?

https://github.com/bitkeeper-scm/little-lang

mannykannot 5 years ago

This language clearly avoids some of the run-time errors that can occur with C, but I would like to learn a little more about the remainder. For example, if you make an out-of-bounds assignment to an array, the array is grown to accommodate it (for +ve offset only, I assume) - but what about out-of-bounds retrieval?

  • luckydude 5 years ago

    You get undef, that's part of the reason we added an undef concept (it's a value that isn't a value, though if you treat it like an int I believe it is zero, like a string and you get "").

    • CyberDildonics 5 years ago

      I think that is a giant design mistake since you are pushing the discovery of an error to some place else in the program, potentially very far from where the error occurred.

      • luckydude 5 years ago

        Without providing an example of how to do it better, I'm not sure I see your point. Yeah, I see the problem you point out.

        Consider

        char *p = 0;

        some complicated code that should have set p but didn't...

        char c = *p; // SEGV

        So do you have a way to push that error all the way back to wherever you think it should be pushed?

        • CyberDildonics 5 years ago

          The person you replied to asked what the behavior was when you access an offset of an array that doesn't exist and you are giving me an example of dereferencing a null pointer.

          The array access should error out on the line that it happens.

          The dereference could print a line of the last assignment, but this isn't what was being talked about.

          • luckydude 5 years ago

            I don't see the array access as any different than a null pointer dereference, in both cases you are asking for something that isn't there.

            In Tcl, stuff just gets auto expanded on assignment and returns "" (I think) on dereference. We chose to return undef. I'm not sure what the problem is.

            • CyberDildonics 5 years ago

              I explained the problem already (the error does not show up where it actually happens).

              I also explained a huge difference between the two already (you know how large an array is and can detect an out of bounds access when it happens).

              • luckydude 5 years ago

                You seem bound and determined to not hear that tcl auto expands arrays as needed. There are no bounds. So there is no error to catch.

                We just thought it would be clever to return undef if you were out of bounds, which tcl code would see as "" which is what you'd get in tcl. But Little code could actually tell you are past the end.

                In my mind, which many have argued isn't the best, it's a reasonable design.

                You keep trying to push backwards to a design point where arrays are fixed in size at declaration and that is not how tcl (or Little) works.

                • zimpenfish 5 years ago

                  > There are no bounds. > clever to return undef if you were out of bounds

                  You can see how this is getting confusing.

                  > So there is no error to catch.

                  Thing is, you're already catching the error because "Little code could actually tell you are past the end" and "return undef if you were out of bounds" - you're just smooshing the error under the carpet into an `undef` return rather than bombing out with an OOB error (which is what I think GP was actually after.)

                  (If Little returns `undef` for OOB and `""` for in-bounds-not-set, you can detect the OOB access error in your own code but that hasn't been made clear, I don't think?)

                  • luckydude 5 years ago

                    Little returns undef for OOB and for in bounds not set. Tcl returns "" for both.

                    The thing that GP was asking for, an OOB error, is not a thing in a language where there are no bounds.

    • IshKebab 5 years ago

      So there's `undef` and `null`? I wonder if there's a popular language that made the same mistake you could have learnt from :-P

      • luckydude 5 years ago

        There is no null, only undef. It's not a value, there is no value that means undef. We implemented by stealing the high order bit from the reference counter that tcl uses for garbage collection. If it is set, the variable undefined, if it isn't, it's a normal variable.

        I thought that was clever given that tcl's reference counter was signed and it only uses positive values. So we made it unsigned and got the bit for free.

        • skybrian 5 years ago

          What happens if you call a Tcl function with an undef argument? Is this running Tcl code on a slightly different runtime, or do they interop in some other way?

          • luckydude 5 years ago

            In Tcl, everything is a string. The string rep of undef is "" so Tcl gets "" but doesn't know that it is undef.

            So yeah, there is some sloppiness there. Tcl tends to use "" as sort of a null or undef so lots of stuff just works but no promises on that.

            This is sloppy simply because the Tcl die hards (are there any left?) refused to see the value of undef, a value for a variable that said there is no value. We used it all over the place, there clearly is value. They didn't see that, Little never got pushed back into the Tcl source base so Tcl never thought about undef.

            It is what it is, we live in an imperfect world. I tried.

  • CyberDildonics 5 years ago

    What would you want a language to do if you try to access an array offset that doesn't exist except for give you a clear error?

    • luckydude 5 years ago

      You are kind of making my point. In tcl, they'd just give you "", but you can't tell the difference between "past the end of the array" or an element where you said

      set foo[i] = ""

      In Little you can tell, we'll return undef (your clear "error" though in these languages it is a supported feature, not an error). So we support the auto expanding array but give you that extra bit of info that you are past the end.

    • mannykannot 5 years ago

      Well, it's that line of thought that prompted my question. It is, of course, a well-known source of problems in C that it will uncomplainingly dereference an invalid pointer.

      • CyberDildonics 5 years ago

        That's actually C avoiding a run time error which is the opposite of what you asked.

        • mannykannot 5 years ago

          You are right, it is avoiding a runtime error, but there have been, and continue to be, many cases where it leads to one. I suppose am asking about things that are undefined behavior in C.

nanofortnight 5 years ago

Is Little embeddable? This seems like a perfect scripting language for embedding into a larger C application.

  • luckydude 5 years ago

    I would think so but I haven't done it. People embed tcl all the time, perl/tk is perl with a tcl interpreter embedded just so they can get at the tk part (gui stuff).

  • ThedarkbOP 5 years ago

    I asked Oscar Bonilla on Twitter a while ago and he said that it should be the same process as Tcl, but beware I haven't tried.

maskedoffender 5 years ago

Bellard's tiny C compiler (tcc) can execute C so fast it's as if it were a scripting language.

https://bellard.org/tcc/

swagonomixxx 5 years ago

> undef(argv[1]); // left shift down the args

Can someone explain what this does? Is this some Perl or Tcl thing? Unfortunately I've never used either :)

  • luckydude 5 years ago

    I'll grant you it is sort of weird. I think that's a perl thing, we just copied how they did it.

    undef is both a function and a (non) value. It is the main reason Little never got pushed back into tcl, the tcl crowd hates the idea that there can be a value for a variable that is undefined. I found that very useful, for example, undef is the error return from any function. Just made sense to me, didn't make sense to the Tcl people.

  • tyingq 5 years ago

    It's not a Perl thing. In Perl, that would set argv[1] to undef. It would not delete or left-shift @ARGV. There is a delete() function that acts similarly, but is discouraged to use on regular arrays. Shift() would be more appropriate in this case.

    Given the context, in little-lang, it appears to delete argv[1] and shift all of the right of that down, such that argv[2] becomes argv[1] and so on. That's so that the the "while (buf = <>)" construct used right below it doesn't process the regex as if it were a file to "grep" through.

    In Perl, you would typically do it this way...

      if (!defined(my $regex=shift(@ARGV))) {
          die("usage: grep regexp [files]");
      }
synergy20 5 years ago

so this is a c-like-interface for tcl/tk libraries? I was thinking it's a c-style lua script alternative so I can use it on embedded boards.

sneak 5 years ago

I support any language that lets me use unless (if!) and until (while!).

I really wish more languages would adopt this syntactic sugar.

peteretep 5 years ago

Strongly recommend removing the Perl camel from the logo as it’s a trademark owned by a commercial entity

rurban 5 years ago

I really like the syntax. But it should be compiled to lua, not tcl.

  • luckydude 5 years ago

    Well the compiler is open source, have at it :-)

    Personally, I would love a gcc --little dialect complete with a String type (and others) that is garbage collected and auto resized just like tcl/Little. With all the other Little goodness in there. Man, that would make C super pleasant. And it wouldn't be a new syntax like Go/Rust/whatever.

dilawar 5 years ago

is there a list of acomputer languagesn(dead or alive) and spoken languages (dead or alive)? Would like to see at what time computer languages are likely to outnumber spoken language.

  • rvense 5 years ago

    The highest estimate for number of natural languages I've seen is about 7,000 living. But I think you'd have to have a very, very restrictive definition of programming language for it to be lower than that.

    • endergen 5 years ago

      Definitely depends on the definition, it seems every programmer and their mother has some toy programming language they poke at.

      • mhd 5 years ago

        Most of which would probably more qualify as dialects in natural language terms. We're all mostly speaking broken Algol with some fancy loan words and maybe a slight lisp.

  • zabzonk 5 years ago

    Unsurprisingly, Wikipedia has both.

forgotmypw17 5 years ago

this is amazing, like a dream come true!

vram22 5 years ago

Has any one else noticed that programming-language-topic threads on HN seem to come in batches, sometimes? I'm not complaining. I like it, since I am a language fan, though not an implementer or lawyer. I have seen this phenomenon at least a few times in the last few years. (Did not check much during Covid.)

  • JNRowe 5 years ago

    I've been enjoying this series of "Breakfast With Forth Week", best one yet.

    It had left me wondering what had caused it. There was a thread a few weeks ago where the old guard were describing an actual attempt to game the system, and I wondered if we were seeing a version of that being played out.

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

  • sidpatil 5 years ago

    It's probably because one link leads to another, and interest in the topic is piqued for a while, until the next new (or old) cool topic comes along.

    • vram22 5 years ago

      Yes, that's probably part of the reason - apart from a fad-of-the-month kind of thing, and also due to genuine interest in the topics.

mastrsushi 5 years ago

This sort of reminds me of the old MUD VM language Pike https://pike.lysator.liu.se/

  • luckydude 5 years ago

    I remember Pike, I looked at it. It was too far away from C for me. I'm a died in the wool C programmer (I started as a kernel programmer and formed some strong opinions there). I get that C is not for everyone but for me, it's enough of a language to do what I want and not filled with this, that, and the other kitchen sink.

    So Little looks a lot more like C than Pike does. And I like it that way. It's not for everyone but C programmers will probably like it.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection