Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Buzz, strongly typed scripting language written in Zig (github.com/buzz-language)
140 points by giann on Nov 21, 2022 | hide | past | favorite | 68 comments



Love it! The only thing that was a “meh” for me was using pipe for comments. It’s the only thing that I found to be unintuitive, which I very much like to see whenever I’m looking at a new language.


I kind of like it. It looks like a blockquote


Do any other languages use it for comments?


The only language I've seen pipe used with comments (not line comments though) is Common Lisp:

  #|
    This is a multi-line comment
  #|
    And they can be nested because this is really just a reader macro
  |#
  |#

I don't think I've ever seen a standalone | for comments, especially since it's so often used as bitwise or logical or.

And here they use \ for bitwise or, and the word `or` for logical or.


Maybe I'm just old, but first thing I would look for in a strongly typed language is int vs float, but all I see here is num. Is a single numeric type expected for modern languages?


I think it's more to do with it being a scripting language. Scripting languages are designed to be quick and easy to write, so instead of having to deal with int/float etc, the language can do it for you.


Makes sense, and I guess it’s semantics, but if the language/interpreter is handling which numeric types to use for me, should it really be sold as “strongly typed” in the main tagline for the language?

Internally, float and int are completely different types, 2’s compliment vs ieee754. Conglomerating them to a “number” feels like weak typing.

(Disclaimer: I’m a grumpy C++ engineer.)

Edit: it does look like a neat/useable language though!


Typing is technically a distinct concept from binary representation, it just happens to be a very useful concept for interpreting bits. If the set of valid operations is known at compile time with no exceptions, I'd call that strong typing regardless of whether the internal representation changes during execution.

The problem I do see with combining int and float is that it means that you always have to be careful with == on any pair of numbers, where a language that does distinguish between the two gives you a clue about when equality will work and when it won't.

But that's a flaw in the number type, not a weakness in the type system.


I will be interesting to see how this combined number data type plays with the Zig/CPP/C interop feature: https://github.com/buzz-language/buzz#call-czig-code


Thanks, yeah that makes a lot of sense. I do tend to conflate the two concepts.


Those are representations, not types. I think they are using the "what can I do with this" definition of type, which is just its public API, and nominality (walks like a duck, quacks like a duck, doesn't mean it's a duck)


They are not ducks, they are two different animals, even if you disregard binary representation.


It may be strong typing, and there are just no ints. This is how JavaScript works: all numbers are f64.


Then what is: 1 << 33


Hmm... it's 2. It seems that the bitwise operators do indeed convert numbers into 32 bit integers (truncating any decimal parts) before applying their operation.


> Numbers are either internally i64 or f64 and are coerced from one to the other as needed

I agree, not quite my preference in scripting languages. I prefer to be able to deal with numeric representation.


I'm not excluding the idea to allow the user to choose between the two. But the language must remain simple and relatively high level so I'm wary of going down that road.


The big problem I see with combining the two types is that it means that a user must always consider that the values they're using may have passed through imprecise floating point arithmetic, so the == operator is always potentially problematic. If you divide the two out into separate types, then the user can use == on ints without any concern, and it better reminds people to be careful with floats.

I definitely wouldn't break it out into int, long, float, double, and unsigned variants. That would be too low level for this kind of language.


I think it's fine to not offer all unsigned/signed variations, but in languages like TypeScript I often miss this distinction. Even Python differentiates between int and float where it is relevant, for example when indexing arrays. Sometimes you just don't want to mix the two.


Segmenting the two and performing conversions implicitly as necessary is fairly standard, the only thing that would be required is... exposing the current implicit behaviour.

Python, Ruby, or Lua do that. That's less "nonsense" than doing the same but hiding it from the user.

"num" also gives a false impression: before checking, I expected JS's (or Lua < 5.3) behaviour: everything is a double, and you only get 53 bits of integer precision (which is quite frustrating).

An alternative if you want

> simple and relatively high level

is to use decimals, at the cost of complicating the implementation.


Exposing how? If you mean documentation, Buzz as not yet its reference manual but it'll definitely be there.


Lua has the same strategy as Buzz around numbers see https://www.lua.org/manual/5.4/manual.html#2.1


> Exposing how? If you mean documentation

No I mean as an actual type, instead of `num` juggling representation internally.


If you want to make a strongly typed language and not repeat the mistakes of Javascript, you should make them distinct. In striving for simplicity it is much easier to accidentally arrive at simplistic.


Not sure what 'num' means in buzz exactly, but it could be something like a Haskell class, choosing the specific instance/implementation automatically, while also allowing explicit specialization if needed.

https://hackage.haskell.org/package/base-4.17.0.0/docs/GHC-N...


I too would really prefer int & float!


Are there any practical advantages to using Zig vs anything else? Presumably, the cross compilation means this should run everywhere for free, but would love to know if there was anything especially easy/hard with respect to the host language.


It's really good for interfacing with C or writing C ffi's. If you're the sort of person who normally programs in a high-level language, then drops down to C for performance, zig is pretty good for that.

(If you want to compare zig and C, there are frankly a lot of reasons to prefer it, at least in the abstract).


Looks neat! Reading the docs only a few things stand out as odd to me:

- The common types are written as fully lowercase, shortened words (str, num, fib) but then function types are written as Function(). That seems like a weird exception.

- The use of a comma to delimit object fields, but a semicolon to delimit static fields, seems arbitrary.

- If brackets around control flow blocks are required, which they seem to be, then parentheses around the conditions seem unnecessary.


Curious what the author is thinking of when calling this a "scripting language"? I personally don't have much trouble imagining a strongly-typed scripting language, but that definitely goes against the flow of the past couple of decades. Is it that it is garbage collected? That's about all I can see that would make this immediately obviously a "scripting language". It doesn't seem like it ought to be intrinsically as slow as what usually gets called a "scripting language".

To be clear, this is an honest question, and possibly something the author should consider answering, intended as feedback, not a criticism. I'm open to it. I'm also curious and I'm sure I'm not the only one. (Either way I definitely would suggest mentioning if it's garbage collected or not. It's an important point.)


Author here. A few points make buzz a “scripting language” in my view: - runs in a VM - garbage collected - high level - “simple” meaning there’s only a handful of concepts to understand to use it

It’s true that we’re not used to scripting languages having a type system. But its a trend that is catching on: python has types, php too and typescript is at its peak in popularity to name a few.


Actually what made me not consider this a "real" scripting language is not any of those things but rather the existence of a non-optional entry point function. Scripting languages typically read code from top of file to bottom to decide what to execute


It’s really hard (impossible?) to have a type system with user defined types and do without a declarative top level.


I think by the non-soft bits (I don't know what simple means) of your definition, Erlang, java, c#, go would be considered "scripting languages", which I think would be a hard sell.

Anyways I don't mean to take away from your work;. It looks very cool.


Multiple passes?


I don’t want to be that person but technically python is a strongly typed scripting language as it has no type coercion but instead uses structural typing.


You might be thinking about the distinction between statically typed and dynamically typed languages. There are plenty of strongly typed scripting languages. Python is strongly typed; JavaScript is weakly typed.


Reading this comment, I realized I always thought:

Scripting == interpreted

Is that not the case?


In my mind scripting means what it is: You read a file like a script from top to bottom and run it. Declarations are actually instructions for a "declarer routine". There's usually no predefined entry point function, and if there is one it's optional.

Compiled/interpreted is kind of besides the point.

Julia (compiled, btw), ruby, python, php, perl, bash, JavaScript thus are all scripting languages.

Java, c, c#, go, f# rust, zig, Erlang, some flavors of lisp, node-style javascript, are not.

There are some corner cases. I consider elixir, for example to be a scripting language for it's own compiler which produces a very much non-scripted result.


I love the idea of a statically typed scripting language! Overall it seems pretty cool.

Really the biggest distraction is that the static typing is lost between int and float with the catch-all num type. I think this will make it harder to program in, not easier (reasoning about where NaN, Inf, under/overflow, rounding etc might occur will depend on some choice it makes internally so as a programmer may need to give up and “assume the worst” everywhere!)

You can still keep it nice and easy and scripty with literals like 1 vs 1.0, and not worrying about number types other than signed Int64 and Float64.


Is there any difference between a statically typed scripting language and a statically typed compiled language that compiles in <.1s?


Versatility of the standard library and ability to write terse programs which achieve a lot. Even if C++ compiled always in under 0.1s, I wouldn’t call it a scripting language, because its standard library is anemic and basic stuff, like finding things in containers, copying things from one container to another, basically anything involving iterators requires such elaborate code that it’s on the opposite side of the spectrum from a scripting language. A scripting language is a tool for quickly performing one-off tasks. Terseness and a rich stdlib are virtues here.


A scripting language and a compiled language are not two distinct things. A scripting language can be compiled if so desired, and JavaScript does so in most browsers for example.

The main difference between a scripting language and a non-scripting language in my opinion is that a scripting language is called through a host program, which offers configuration and a standard library, while a non-scripting language runs by itself, using the operating system as its environment.


I like this! It looks really comfy to write.


> No nonsense coercion

Given that the focus is on being unambiguous I found this line a bit amusing. Maybe it’s me but I can’t tell for sure whether this describes a quality of the language’s coercion mechanism or a promise that the language will include no such “nonsense” like e.g. javascript :)


This means the language will never coerce things for you implicitly. Booleans are true and false not 1 and 0 or “true” and “false” etc.


You could argue that hiding ints and floats behind “num” is implicit conversion


Fair point


Looks nice. Two things that turn me off:

- pipe for comments

- error handling via exceptions: I prefer monadic Result<Success, Error> types a la Rust, exceptions obscure control flow and are try/catch us unnecessarily verbose


I find the choice to sacrifice | for comments rather peculiar. It's so commonplace for | to be or.


Can the ffi be made more seamless? It's rather annoying doing it by hand.


It’s planned yes


just for your information: the logo resembles islamic flags


It’s pretty obviously an astronaut looking out at space. Buzz (Aldrin/Lightyear), get it? Would it be an issue if it did resemble an Islamic symbol?


> It’s pretty obviously an astronaut looking out at space.

Props to you for seeing it, but I don’t think it’s obvious at all until pointed out.


I disagree, they usually have green or black. I don't recollect them using stars either.


> I disagree, they usually have green or black.

The logo is black, which seems to qualify as "green or black"?

Red and white are also very common (ottoman flag, turkey, tunisia).

> I don't recollect them using stars either.

"Star and crescent" has been common muslim iconography since the 14th century, and the ottoman empire (which introduced them).


The logo shows purple to me and it isn't a crescent, cuts off ar the bottom.


> The logo shows purple to me

It seems to be an extremely dark purple, on a white background it's genuinely indistinguishable from black.

> it isn't a crescent, cuts off at the bottom.

Which is close enough to a crescent for

> resembles islamic flags

to be a perfectly valid take.


It's actually not a very valid take at all. It is VERY clearly not black I suggest your monitor is extremely poorly calibrated if it appears so. It not only isn't a crescent its not even a vaguely crescent shaped object. In Muslim iconography the crescent is a moon an object in the foreground not the background formed by putting any circular item offset inside any other.

It's reaching.


It is a subjective opinion and I strongly and subjectively disagree.


I don’t think it matters in the slightest, but you’re absolutely correct, there is a resemblance. I don’t know how that became open to subjective debate.

https://en.wikipedia.org/wiki/Star_and_crescent


Yeah, I think making the icon an octagon rather than a circle would help.


No, it resembles a safety pin and stars, the well known Society for Communist Seamstresses flag.


Safety pin? No its an astronaut and some stars.


> object ...

You already lost me there. ¯\_(ツ)_/¯

https://suzdalnitski.medium.com/oop-will-make-you-suffer-846...


They are more like structs with methods. There’s no inheritance only protocols (interfaces) you can conform to.

Buzz is not an OOP language.


OK! That's reasonable. But then the naming implies more...




Consider applying for YC's W25 batch! Applications are open till Nov 12.

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

Search: