Hacker Newsnew | past | comments | ask | show | jobs | submit | Decabytes's commentslogin

> Why have operators at all?

I mean as an avid Lisp fan, I feel like Lisp basically answers the question of how much syntax you need in a langauge. I must admit though, not having to deal with operators precedence is really nice

  (mod (+ x (* 2 step)) width)

Also, having them if you want is nice:

  1> let ((x 3) (step 2) (width 5)) ((2 * step + x) mod width)
  2
This is TXR Lisp with auto-infix and auto-compound enabled for the REPL:

  2> *listener-auto-infix-p*
  t
  3> *listener-auto-compound-p*
  t
So we can omit the outermost parentheses, and infix syntax is automatically recognized, freely intermixed with regular Lisp, as if the (ifx ...) macro were wrapped around the input.

I've come up with a very good way of handling infix in Lisp, and documented it in a decent amount of detail as well, not just as a manual for the user but anyone wanting to implement something similar.

https://www.nongnu.org/txr/txr-manpage.html#N-BEB6083E


Regarding operators, there are 3 distinct problems.

One is to allow the use of simple mathematical symbols as names for functions, instead of allowing only alphanumeric identifiers.

Most programming languages allow only a small fixed set of symbols to be used as "operators", i.e. as function names.

The better solution is to allow any Unicode character from certain categories, e.g. "Sm" and "Po" ("Symbol, math" and "Punctuation, other"), which does not have an already assigned role in the language syntax, to be used as a function name.

Most LISP variants allow the use of various kinds of character symbols as function names.

The second problem is overloading. Overloading must be treated uniformly for any kind of functions, regardless if their names are identifiers or operator symbols, i.e. not like in Java, where forbidding operator overloading was a mistake (that was an overreaction to C++, which allows the overloading of a few "operators" that are not normal functions and whose overloading should not have been allowed, e.g. the comma operator).

The overloading of operators, especially for user-defined data types is something absolutely essential for scientific and technical computing.

The majority of programmers have not been exposed to programs that contain a great amount of computations, so they are accustomed only with simple expressions that contain a few variables.

In scientific and technical computing it is very frequent to have very big expressions, which may contain a large number of operations and variables, where the variables may have various types, like complex numbers, vectors, matrices, complex vectors, complex matrices, or there may be a type system with distinct types for various physical quantities, like voltages, electric currents, capacitances and so on.

Anyone who had to write frequently such big expressions will definitely prefer, both for writing and for reading, to use overloaded operator symbols instead of long function names, which would fill most of the visual space with superfluous characters, obscuring the structure of the big expression.

The third problem is the syntax of function invocation. Most programming languages allow functions whose names are identifiers to use only prefix invocation but for some symbolic operators they allow infix invocation.

Here I also prefer the languages that do not differentiate between functions with alphanumeric names and functions with symbolic names (i.e. operators). There are languages where for any function it may be specified that it must be invoked as an infix operator, if this is desired.

Which is the best between the 3 classic solutions for expression syntax, traditional expressions with infix operators and multi-level precedence rules (like in FORTRAN and ALGOL), expressions with infix operators and a unique precedence rule for all operators (like in APL) and expressions without infix operators (like in LISP), is debatable.

Each of the 3 solutions has advantages and disadvantages, so the choice between them is a matter of personal preferences.


Here is where I think Zig shines. When you are a high level programmer that needs to drop down to a low level programming language for performance reasons. The issue with doing that as a high level programmer is that you don't do a lot of low level work frequently.

So unless you work in another domain where you do a lot of low level programming, then every time you drop down you will be out of practice. This favors using a simpler low level language, with low friction for integration. Rust and C++ don't handle being used infrequently, but C with it's simpler standard library and syntax fits this nicely. But it doesn't have things you expect for a modern programming language, and it is also has a lot of dangerous footguns that are easy to forget if you are out of practice

In comes Zig. It's low level, comes with it's own toolchain that makes it pleasant to work with, easy to cross compile, has more safety features built in that C, but is not overly complicated. The code tends to be more verbose, but also more straightforward. So it's a perfect language to pair, when you know you won't be able to do everything in a high level language.

For me that's what seals the deal. I'd argue that Odin has a nicer syntax, but there is a reason that tools like cargo-zigbuild^1 exists. The fact projects not related to Zig are willing to ship Zig toolchains to make lives easier is a testament to how seriously Zig takes this.

1. https://crates.io/crates/cargo-zigbuild


Looking at it from an existing knowledge base and error checking point of view, I feel like C++ smart pointers or Rust is a better option for someone doing a dangerous low level thing rarely. I'm not sure Zig is really all that favorable a choice in your given scenario.

Rust unsafe is less safe than writing C code. Rust is not good language for writing "unsafe code". C++ smart pointers are really bad compared to arena allocators, and not allocating at all. It's very easy to end up with dangling references in C++, or double frees with smart pointers. Also the fact that C++ initialization itself is a huge foot gun.

I think if you need to get so close to the bare metal that you'd need unsafe Rust then the equivalent Zig is also too dangerous to use "infrequently". Stuff like writing raw assembly, pointer twiddling, volatile stores or fetches - I would hire somebody with lots more experience to do that properly once if you need it.

On the other hand if safe Rust is an option that's way more handholding than you're getting in Zig. Lots of "Whoops I forgot" mistakes won't even compile in safe Rust because it couldn't see why they're OK and that's required but in Zig now you've written a bug.


For clarity in this dual programming language scenario I'm talking about, I'm writing a user facing app that's mostly a lot of business logic.

It's running slow so I profile it and I see my math function in pure Dart (or whatever language you are writing in) is the hot spot, and pressures the garbage collector too much, so I rewrite the function in a lower level language that doesn't have as much overhead, to speed things up. Then I just call it from the higher level language through the FFI.

The benefit of Zig is the syntax is simple, and the build steps are simple, so it doesn't slow down app development too much


For this example the safe Rust seems like exactly the right choice to me but that's just me.

I am not 100% opposed to AI and I spent multi hundreds of dollars across the major players right now, but I'll see what I can add.

> At some point, execution speed starts to matter more than the elegance of the code.

This sentiment has been with us for a long time, and AI has only made it worse. Many people have experienced the damaging effects that focusing on execution speed have had on our lives, and you would think if AI makes us 10x faster, we could spend half that time actually making programs more performant and secure. But all of the gains always funnel into speed, when we have the golden opportunity to make things better.

Then there are the players that make it. Casey Muratori recently did a video called "It just Happened" where Eric Schmidt gives a commencement speech and washes his hands of the negative things that have happened in it, even though his decisions at Google and the technology he helped create made a lot of that happen. A quote from Casey's Video

> This is a case where someone who had direct decision-making authority during the time period when the very worst most dystopian parts of the technology business model were developed, perfected and entrenched. And he is giving this commencement speech to a group of students who have known nothing but that their whole lives. They're not like me. They didn't know a time before all of this. They didn't experience technology in the 80s or something like this.

One of the most important things in that quote is that there are people who have known nothing but a predatory, privacy invasive technology world. When that is your baseline, new technology that could advance that at 10x speed does not feel great. And now it requires only a couple bad actors and a subscription to make that happen.

At work we are mandated to use AI. That feels bad for a lot of reasons. But one of the worse is having to review AI generated code. I have never liked reviewing other peoples PRs, and now with the speed AI code is created, I could spend the whole day just doing that. So now my job is worse because I have to do more of the part I like the least.

Next, I've been thinking a lot about "the human scale of things". To me that means slowing down, and not consuming things faster than my lizard brain can understand. While I might be able to go 10x faster, unless I'm doing something I've done a million times before, I will not be able to keep that much code in my head. So I quickly lose understandings of projects, and I have to fight hard to rebuild my knowledge.

Lastly, as someone who has "vibecoded" an app, It feels completely impersonal. Yea I had the idea, and yea I had to type the prompts, but producing a whole mountain of code over the course of weeks or months (I've done both) just leaves me feeling empty on the inside. There is still a selfish human component to the programming that I and I suspect others do, and AI takes away from that

I'm not sure what the solution is though. Do we say, if you don't want to take ownership over the bad things that happen then we will down play your part in the good? Do we try to set up organizations that persecute those accountable? Should Eric Schmidt be in jail? Should he be fined? Do we as developers try to use the tools "for good?" I don't know, and I'd love to know what other people have to say on this


In Grad school I remember learning Python 2, and there was one particular night where an assignment of mine just wasn’t working and no searches were helping me. I was frustrated to the point of tears, and when I solved it, it wasn’t with some triumphant yell. I just remember being so tired, closing my laptop and going to sleep.

I’m sure I wouldn’t be the programmer I am without that experience, but I am Not sure I would have willingly put myself through that if LLMs existed at that point


Blizzard's Real ID system would fix all of this. It was ahead of it's time /s

There is an idea I've been kicking around for a long time, which I'll just call dual programming. The idea is to develop a stack that consists of just two programming languages, 1 higher level language, and one lower level language. You are supposed to do as much programming as you can in the high level language, and only drop into the low level language as needed. The problem is that unless you already know a low level programming language really well, you'll most likely have to re familiarize yourself with the language before doing the low level stuff.

This makes Cpp and Rust harder to use then say C, so C becomes the default for me. But C is not without its issues of which we are aware. But Zig feels like it could fill that sweet spot really well, being simple enough that it's easier to pick up after a long break, but still coming with a lot of modern tooling that makes programming easier.


> You are supposed to do as much programming as you can in the high level language, and only drop into the low level language as needed.

I think that's a neat idea, but in the reverse: do as much as you can in the lower level language, and only go up to the high level language when the convenience is worth the cost.

Roc allows this: every program has a platform written in a low-level language, and then the Roc program uses the API that the platform exposes.

https://www.roc-lang.org/

Then how you want to balance high vs low is of course up to you :^)


roc lang looks very interesting, I see they use a lot of Zig and Rust, very unusual combo I think.

I think they are switching from Rust to Zig. I don’t recall exactly, but they talked about it in a video where the creator of Roc interviewed the creator of Zig.

https://www.youtube.com/watch?v=w74rC-6caxE


thanks, will watch it later

C# is close to achieving that goal.

People always laugh when I mention C# in this regard. It has so many things, like pointer, you can define that memory alignment works like in C, SIMD, AoT compilation, Span<T>. I think you can do pretty much C like programming in C#.

We had several of such languages in the 2000's. C# is basically becoming what Modula-3 already offered.

Or just use one language that does both high level and low level programming well, such as Rust. I use it for everything now as I haven't found anything it can't do yet, especially with its OCaml like type system.

A common combo for this is (was?) C and Lua. Lua is intended to be a embedded language, so good for Interop, but also also high level and easy to use.

There's a reason why Factorio uses Lua as it's scripting level language


The OG of these is probably C and Assembly. C and (Emacs) Lisp is well known. Arguably, it's the entire reason we have Python. But if you want to pair Zig against something, I would look at Lua.

this was the general motivation for my project zigler:

https://github.com/E-xyza/zigler


Very cool use of Elixir! I have been considering the Fig Stack (F# + Zig) myself, so I'm excited to see Zig being paired with a Functional Language

I believe that is how SpaCy is developed. Models are implemented in Cython and user facing API in Python.

Neovim comes to mind. It uses clang as the core, and luajit as the extension layer on top.

Objective-C and C?

I really appreciate Casey for making this video. The two quotes that stand out to me are

> This is a case where someone who had direct decision-making authority during the time period when the very worst most dystopian parts of the technology business model were developed, perfected and entrenched. And he is giving this commencement speech to a group of students who have known nothing but that their whole lives. They're not like me. They didn't know a time before all of this. They didn't experience technology in the 80s or something like this.

I think this is hugely important context. New technologies are not being built in a vacuum. It's not like we haven't seen the negative side effects of these new technologies play out already, and like Casey said, many of the people who are voicing their concerns have only gotten to live through the bad parts.

> It didn't just happen because the tool was let loose on the public and it just happened. People built the bad parts of it. They did that.

There is a JFK quote that I think accurately sums up the issue

> Victory has a hundred fathers and defeat is an orphan.

People just don't want to be associated with bad things. Billionaires don't want to be associated with the negative parts of capitalism, CEOs don't want to be associated with the terrible things their companies do, and businesses that do wrong want to settle out of court, with no public statement of blame.

I'm not sure what the solution is though. Do we say, if you don't want to take ownership over the bad things that happen then we will down play your part in the good? Do we try to set up organizations that persecute those accountable? Should Eric Schmidt be in jail? Should he be fined? Do we as developers try to use the tools "for good?" I don't know, and I'd love to know what other people have to say on this


Just want to throw the other Google language into the ring. While I would say Dart has a few more fancy language features than Go, it has an extremely strong and modern cli tool, which is a one stop shop for all your formatting, linking, and project building needs. It even grades how well your project is constructed before you publish it to pub.dev


What does it bring to the table that isn't achievable with Cargo?

I just feel like Dart doesn't offer enough for a fairly standard OOP lang which isn't particularly fast and doesn't have the library ecosystem or vast training data of Rust, Go etc


> What does it bring to the table that isn't achievable with Cargo?

Speaking purely about the cli dart devtool (flutter and debugging) dart compile (More options but the big one is JavaScript transpilation) dart info (outputs diagnostic information about installed dart toolchain)

> which isn't particularly fast

Against other programming languages that are also garbage collected Dart compares favorably, though it's implementations of things typically aims for user accessibility over maximum performance. For example a Dart Isolate is much more heavy weight than a goroutine due to it's higher startup cost and additional memory per worker. The advantage is that it has its own memory, own event loop, and communicates with other isolates only by message passing, so it's much harder to mess up.

But where Dart shines for me is in two instances. The first is as a Python programmer that wants to work in a statically typed, ahead of time compiled language. Dart fits the bill here, and covers a weakness many programming languages have which is user facing GUIs. I would argue nothing comes close to Flutter when it comes to slapping together cross platform GUIS that just work. Dart is also very good on the front and backend (with more emphasis on the frontend) of web development, and can be integrated into an existing project very well through it's ability to compile into JavaScript. Typescript definitely eats Dart's lunch here, and Go more so for the backend, but very few languages can do Webdev in a way that feels natural and due to many design decisions of the past Dart is better than most. So Dart is good for packaged user facing apps.

This also makes it a strong contender as the higher level language to pair with a lower level language. You mentioned Rust, and Dart has a Flutter Rust Bridge^1 which allows you to write normal Rust code that automatically has the glue code generated. The native code interaction story gets even better through Dart's Hooks^2, Which allow you to integrate and compile or download native assets into your Dart projects directly through Darts build interface.

> doesn't have the library ecosystem or vast training data of Rust, Go etc

LLMs are better at handling niche languages than they have ever been. And the fact that Dart is not applied broadly, in the same way Python is, means you don't need a million examples to cover the most common use cases.

1. https://pub.dev/packages/flutter_rust_bridge 2. https://dart.dev/tools/hooks


How do the various BSDs run on framework laptops?


I dual boot OpenBSD on it, and it's been doing fine. The out of the box experience is pretty bare although the default window manager cwm is surprisingly nice once you get to know it. Note that apmd, the power management daemon used to manage CPU speed and low-battery suspend, is not enabled by default. The high-DPI screen required some adjustments in Xresources (I haven't dared try a multi-monitor, mixed DPI setup).

NetBSD seemed okay to but I've only used it a little bit. It actually set up X pretty well for the screen using some built in script with heuristics to determine font size from the screen metrics.


There's been a bunch of progress on FreeBSD, and OpenBSD isn't that much worse


No wifi driver for Framework 16. Was fun installing (and surprisingly quick) and playing around a little. But unfortunately that's a dealbreaker for me.


Power management, webcam, trackpad, accessories, etc tend not to be a good fit for niche BSD and Linux. Stick to desktop or server.


Trackpad? I've had OpenBSD on ~6 laptops, old and new, but the trackpad always worked fine


Do you disagree with my comment? Or just about trackpad?


huh? I've been running Arch exclusively on my laptops for at least 7 years


Thinkpad? Or dell?

How is the battery life?


Let's see, System 76, previously Dell and Samsung.

All the pretty much the smallest and lightest I could find. So not fantastic, but good enough. For me, battery life is much lower on the list than "small and lightweight" and "works well with Linux".


When I was in grad school, my mentor once said, that he didn’t actually see programming as anything more than a tool to solve the problems he needed to solve. As someone who was excited about learning to program, I couldn’t understand it. As I’ve gotten older, I’ve come to understand him more. The language a program is written should be far down the list of reasons to use a programming language. Same with who happens to be the BFDL for the language, or what streamer is using it.

What matters more is if it does what you want it to do, and is well maintained.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: