Live data from Hacker News

RBS, Ruby’s new type signature language

developer.squareup.com

321–330 of 340 posts

Re: RBS, Ruby’s new type signature language

#321

Earlier quoted context omitted.

Indeed. To expand on your point: yep, it's incorrect. An untyped language is a language in which there is no concept of type. Assembly languages tend to be untyped. Forth is untyped. The Ruby and Python languages do have the concept of type, it's just that they're dynamically typed, not statically typed. They check types at runtime.

But when you have things like "duck typing", don't you think "they check types at runtime" becomes less meaningful? The majority of functions written in Python, even the ones that have type annotations, do not effectively have "assert isinstance(...)" in the program text below their signature, which is what I'd expect after reading "check types at runtime". Also, Python now has (in its stdlib!) things like typing.Pro…

> The majority of functions written in Python, even the ones that have type annotations, do not effectively have "assert isinstance(...)" in the program text below their signature

It's true that types aren't checked in the act of passing a value as an argument, but at bottom, Python still has a concept of types, and they are still checked at runtime. Try the following and you'll see Python check your types and determine that there's an error:

    "Hello" + 42
This never happens in, say, Haskell (statically typed and never performs runtime type checks) or in Forth (untyped, no concept of type at all).

> Python now has (in its stdlib!) things like typing.Protocol, which is almost exclusively checked at type checking time

Yes, Python is now adding optional static typing, and of course, JavaScript has TypeScript. I'm afraid I don't know a lot about these new systems but presumably the end result is that type errors can occur either at compile-time (or static type-checking time, or whatever we call it) or at runtime. This isn't exactly anything new, it's always been possible in Java for instance, which has always permitted downcasts, and has always had covariant array types, checking both at runtime. [0] This is despite being a statically typed language where all variables must have a fixed type, the type they are declared with. (Remember that a variable's type is distinct from the precise class of a pointed-to object.)

We can draw a distinction between statically typed languages like Java where there's still a need for runtime type checks, and statically typed languages like Haskell where there's no need for runtime type checks. Type theorists use the term soundness for this property: in a language with a sound type system, a program that is successfully validated by the static type system can never have a type-related error at runtime. In engineering terms then, a sound type system means you don't need to check types at runtime, as 100% of type errors are caught by the static type system and there's no way for type errors to ever arise at runtime.

I used Haskell as an example, rather than C, because although C doesn't give us runtime type-checks, C programs can still go haywire if you make a mistake in your program (termed undefined behaviour). C has an unsound type system, and it lacks runtime checks. This is one reason C is so famously 'unsafe'.

So anyway, we have the situation where Python code can encounter type errors at compile time or at runtime, and Java can encounter type errors at compile time or at runtime, but we call Python dynamically typed and we call Java statically typed. The difference is that in Java, a variable must be declared with a fixed type, unlike in Python.

Things can get messy in the middle-ground: in C#, the dynamic keyword allows for true dynamic typing, where a variable's type is determined at runtime. [1] So you could write a C# program in traditional Python style, where there's very little compile-time type-checking. And you could write a modern Python3 program using lots of static type assertions, minimising the opportunity for runtime type errors. We'll still call the C# language 'statically typed' as it's typically true of C# code, and we'll probably still call Python 'dynamically typed', as that will probably remain typically true of Python code.

Disclaimer: I'm not a type theorist or a programming language researcher, corrections welcome if I've got anything wrong.

[0] https://news.ycombinator.com/item?id=13050491

[1] https://docs.microsoft.com/en-us/dotnet/csharp/programming-g...

Re: RBS, Ruby’s new type signature language

#322
post #242

Earlier quoted context omitted.

What is the difference in approach between these? I've programmed extensively in dynamic and static languages, and don't understand what you're talking about. Less verbose, I might concede. More robust though, I need some more evidence.

Reminds me of Rich Hickey’s “Maybe Not” speech, which I understand him suggesting that programming with “sets” is better than programming with “records” that may contain optional values.

Yes, I know it and he seems to mostly ignore the fact that you can still fall back to manual typechecking in a statically typed language. That’s the part I don’t get. There’s nothing stopping you from manipulating JSON structurally in a static language.

Re: RBS, Ruby’s new type signature language

#323
post #309

Earlier quoted context omitted.

Examples like the last one about Python are why I think it’s approximately meaningless as a descriptor. I don’t see why dynamic languages should have any implicit conversions at all.

Where you store the type information and when you do the type check is a separate question from whether you do the type conversions automatically or not. I think a more interesting question is typecasts, like happens in languages like Java and C#. These languages are nominally statically typed, but they retains some type information at run-time, so that you can perform run-time type conversions, which requires run-ti…

You’re muddying the waters. Static and dynamic have a much clearer distinction between them than “strong” and “weak” typing do. These things aren’t binary but that doesn’t mean they are equally descriptive terms.

Java is a statically typed language with late binding implemented through subtype polymorphism and its type system has been explored pretty extensively in the literature.

Re: RBS, Ruby’s new type signature language

#324
post #226

Earlier quoted context omitted.

There are huge debates at Google internally over required vs optional in proto2 and proto3. Beyond that I think you’re operating from a misconception about JSON parsing in static languages. There’s no requirement to convert to domain objects and reject data that doesn’t fit on a triviality, you’re just required to specify explicitly what happens when you encounter unexpected structure or data.

Sorry if I wasn't being clear. I'm not saying that's the only way it can work in static languages. I'm saying that that's the way it tends to work out in practice, because the ergonomics of most popular static languages tend to discourage a less brittle approach. Whereas the ergonomics of popular dynamic languages tend to favor an approach that I find, for this specific purpose, to be both less verbose and more robus…

There may be valid reasons to deserialize in a stricter way. Consider this scenario: https://issues.redhat.com/browse/HAWKULAR-451?focusedComment...

> For example, suppose we have JSON that represents a set of metric data (this isn't our real JSON, this is just a thought experiment) that should look like this, with "tags" being optional attribute: { "id": "1", "timestamp":"12:30pm", "value":"999", "tags": [ "myapp" ] }

> Suppose a python client sends tags but calls the attribute "tag" rather than "tags" (its missing the "s"). Its an optional attribute, so the server won't consider it an error if the "tags" attribute is missing. But it also won't fail due to this unknown attribute called "tag" - it will just silently ignore it now. The Python developer is wondering why his tags aren't being stored - he is getting no errors but they are just silently being ignored. He would need to figure out he is sending in the wrong attribute name, with no error messages to help him out.

> That's the use-case I'm asking about - the "silent error" that will occur due to malformed JSON messages.

Re: RBS, Ruby’s new type signature language

#325
post #224

Earlier quoted context omitted.

I don't use ruby, I am genuinely interested - why is it great? I'm assuming if it were ever allowed, it would be a use-at-will feature and wouldn't affect anyone who didn't use it. Typescript has probably doubled if not more my speed and accuracy since I've adopted it - yet I still do plenty of things in normal javascript. These days I'm usually unhappy when something does not have typings because it can make it terr…

It's great because Ruby is an Object-Oriented Programming language. Just saying that is an understatement; Ruby lives and breathes Object Oriented philosophies. It was made for them. The conflict here is that object oriented philosophies aren't actually about objects. They're about communication between objects. The messaging between objects. As per Alan Kay himself: > I'm sorry that I long ago coined the term "objec…

Agreed. I prefer typed but also really like Ruby as a dynamic language.

Re: RBS, Ruby’s new type signature language

#326
post #270

Earlier quoted context omitted.

I've worked across a wide range of industries over several years, and it's always been pretty similar. You should be building the business constraints into your types so that errors in the business logic become errors in the types - in my experience if you actually work with the type system then most errors become type errors. If you've got examples of the kind of errors you're talking about then I could try to be mo…

Not the GP, but here is a scenario that I am interested in understanding from the perspective of types. A calculation that involves 21 parameters (in a particular insurance industry underwriting) yields a number. A threshold is read from the database. This threshold could change every month. Suppose that the current value of the threshold is 0.78. The calculation above can yield an `x` with the following cases: (i) x…

Sure. Create a type that represents x being <= that threshold, with a private constructor. Only allow constructing it via a factory method that requires it to be an x that should be <= the threshold. Then whenever you have a value of that type, you know that it's legitimately <= the threshold, and the bug becomes impossible.

Re: RBS, Ruby’s new type signature language

#327
post #270

Earlier quoted context omitted.

I've worked across a wide range of industries over several years, and it's always been pretty similar. You should be building the business constraints into your types so that errors in the business logic become errors in the types - in my experience if you actually work with the type system then most errors become type errors. If you've got examples of the kind of errors you're talking about then I could try to be mo…

Not the GP, but here is a scenario that I am interested in understanding from the perspective of types. A calculation that involves 21 parameters (in a particular insurance industry underwriting) yields a number. A threshold is read from the database. This threshold could change every month. Suppose that the current value of the threshold is 0.78. The calculation above can yield an `x` with the following cases: (i) x…

This description doesn't quite make sense. If the threshold is regularly changing, the calculation can output the same result number for the same 21 parameters and have it be a bug or not a bug from month to month, depending on the threshold. How can you write a test for that without locking in the threshold? Indeed, without hard-coding the threshold in the calculation itself?

Re: RBS, Ruby’s new type signature language

#328
post #16

Can someone explain why the types cannot live in Ruby code itself (after an appropriate version bump)? Python 3 incorporated types into the language itself, in a similar way (though non-reified) to PHP. This seems much easier to deal with than requiring two files (.rb and .rbs) to describe a single data structure.

Based on the relative smoothness of Ruby version transitions versus Python, I trust Matz’s preference on this implicitly. One good thing about it being external is that you can optionally and experimentally annotate existing code without munging up your source files. At least so long as this is a bleeding edge feature, that separation makes a lot of sense to me. It’ll be a while before anyone can be confident in a pa…

> It’ll be a while before anyone can be confident in a particular model for how this should work, until it’s been in use for a good long while.

Check out the OCaml community, interface files have been use there since basically day one, and are generally well-liked for how clean they allow the implementations to be.

Re: RBS, Ruby’s new type signature language

#329
post #62

Earlier quoted context omitted.

Yep. A good IDE to a first approximation doesn't allow compilation errors to occur because you are auto-completing everything, including symbol completion based on the type at cursor, etc. Jetbrains is a wonderful company.

Since the advent of LSP, I think the value proposition of a full featured IDE has been greatly diminished. For example, I used to use Intellij for Scala but recently switched to Emacs+Metals and haven't really missed anything. In fact, it's probably an even better editing experience. Intellij still has better refactoring (though I don't use it much), and the integrated debugger and database viewer are really nice. I'…

Does Metals have a feature to add parameter names at method callsites? I use that IntelliJ feature of the Scala plugin all the time, it's such a lifesaver.

Re: RBS, Ruby’s new type signature language

#330
post #77
post #32

Earlier quoted context omitted.

You don't want to switch to a half baked language for anything serious.

How is Crystal a "half baked language"?

It's at version 0.3.5 currently and their latest blog post is about how their main goal is to reach 1.0 which will be stable.
Post reply on HN