4 ms·
> How am I supposed to learn the language's semantics from a lexer? Not what I wanted to achieve, but the lexer contains some frequently used methods and is fa
by Svenskunganka 10y ago
> How am I supposed to learn the language's semantics from a lexer?
Not what I wanted to achieve, but the lexer contains some frequently used methods and is fairly simple and straight-forward, but if you want to learn the semantics why not just go to their docs? https://crystal-lang.org/docs/syntax_and_semantics/index.html https://crystal-lang.org/docs/syntax_and_semantics/index.htm...
> Consider this use case: I spawn five fibers. Can I send the same mutable object to all five? If so, can they attempt to mutate the object without properly taking turns? (e.g., using a mutex)
Taken from the docs:
Crystal has Channels inspired by CSP[1]. They allow communicating data between fibers without sharing memory and without having to worry about locks, semaphores or other special structures.
...
Because at this moment there's only a single thread executing your code, accessing and modifying a global variable in different fibers will work just fine. However, once multiple threads (parallelism) is introduced in the language, it might break. That's why the recommended mechanism to communicate data is using channels and sending messages between them. Internally, a channel implements all the locking mechanisms to avoid data races, but from the outside you use them as communication primitives, so you (the user) don't have to use locks.
[1] - https://en.wikipedia.org/wiki/Communicating_sequential_processes https://en.wikipedia.org/wiki/Communicating_sequential_proce...
- catnaroek 10y ago> but if you want to learn the semantics why not just go to their docs? https://crystal-lang.org/docs/syntax_and_semantics/index.html https://crystal-lang.org/docs/syntax_and_semantics/index.htm... Yep, fair enough. I'm somewhat worried about how abstract classes work: https://crystal-lang.org/docs/syntax_and_semantics/virtual_and_abstract_types.html https://crystal-lang.org/docs/syntax_and_semantics/virtual_a... Apparently, Crystal can infer the methods of an abstract class from the methods of its subclasses. In the Animal/Dog/Cat example, what happens if, in a separate module, if define a Snake class that doesn't have a `talk` method? There are several possibilities, sadly all pretty bad: (0) Does the type checker retroactively decide that not all Animals can talk? (1) Does the type checker decide that Animal subclasses can't be defined in a separate module? (2) Does the type checker decide that, if an Animal subclass is defined in a separate module, it must have all the common methods to all Animal subclasses defined in the same module as Animal? (3) Is type checking not modular? > That's why the recommended mechanism to communicate data is using channels and sending messages between them. I'm asking about the errors that the language prevents, not the community's conventions.
- Svenskunganka 10y ago> In the Animal/Dog/Cat example, what happens if, in a separate module, if define a Snake class that doesn't have a `talk` method? There are several possibilities, sadly all pretty bad The abstract class defines which methods every class that inherits from it must define by using abstract methods. If you write a class that inherits from an abstract class, and you do not define a method that the abstract class says that you absolutely must define, the compiler will raise an error for you. You can inherit from classes between modules. > I'm asking about the errors that the language prevents, not the community's conventions. I haven't actually tried it, definitely something I'll check out another time. I understand your concern though!
- catnaroek 10y ago> The abstract class defines which methods every class that inherits from it must define by using abstract methods. In their example, the type checker can infer that Animal has a `talk` method, even if it's never explicitly defined: abstract class Animal # no talk method here! end class Dog < Animal def talk "Woof!" end end class Cat < Animal def talk "Miau" end end class Person getter pet def initialize(@name : String, @pet : Animal) end end john = Person.new "John", Dog.new In their own words, “Now the code compiles:” john.pet.talk #=> "Woof!" Now, what happens if, in a separate module, I define a Snake subclass of Animal, without a talk method? What happens in this corner case isn't documented anywhere. Type system design is very serious business, and can't be done by mindless trial and error. When a type system has a safety hole, patching it is pretty much guaranteed to break other people's code.
- asterite 10y agoIt will simply stop compiling the code and it will say "undefined method 'talk' for Snake". You will get a similar error if `talk` is defined as an abstract method in the base abstract class. So abstract methods are just a standard way to document this and to improve error messages. There's no safety hole here.