I've had very similar experience: I try to port non-trivial, but still rather simple functional code, for example containing a couple of nested closures, and the compiler crashes. And it seems that the Xcode playground, the command line compiler and REPL all behave a bit differently. In one case playground works, but REPL crashes, in another, compiler works, REPL has trouble of figuring out types. I have absolutely n…
Microsoft's work on C# compiler (Roslyn) is amazing: they offer compiler-as-a-library so the IDE, plugins and debugger use the same backend as the compiler itself. I wish at some point Apple could adopt a similar approach.
Smashing Swift
41–50 of 150 posts
Re: Smashing Swift
#42Still, I look at the Swift with a low-level colored glasses: I don't care if this or that category theory aspect is covered or not. I don't care if you can imagine some nicer syntax for something (everybody can). I really care how good and how often Swift can be used instead of C, not being slower and not using more resources. I know, is nicer. But for me, if it has GC, it's a no go. I see Swift as something where I…
Re: Smashing Swift
#43Swift seems like a nice lang, but I'm surprised that proprietary, single platform language is getting so much traction on HN. Is it because ObjectiveC is as shitty as it seems at first sight (for C like langs dev) ?
Re: Smashing Swift
#44Swift seems like a nice lang, but I'm surprised that proprietary, single platform language is getting so much traction on HN. Is it because ObjectiveC is as shitty as it seems at first sight (for C like langs dev) ?
Re: Smashing Swift
#45I successfully got the Functor example to work like this: protocol Functor { typealias T typealias FunctorResult func map (mappingFunction: T -> P) -> FunctorResult } extension Dictionary : Functor { func map (mappingFunction: ValueType -> P) -> Dictionary { var newDict:Dictionary = [:] for (key, value) in self { newDict[key] = mappingFunction(value) } return newDict } }
Put another way, you need to specify FunctorResult at implementation time, and the whole point is to only have to specify it at call time.
Re: Smashing Swift
#46Still, I look at the Swift with a low-level colored glasses: I don't care if this or that category theory aspect is covered or not. I don't care if you can imagine some nicer syntax for something (everybody can). I really care how good and how often Swift can be used instead of C, not being slower and not using more resources. I know, is nicer. But for me, if it has GC, it's a no go. I see Swift as something where I…
The language is not "innovative" as they claim, so people are expecting at least some learning from mistakes of prior languages. They could've hired some smart people from more software-oriented companies or something.
Re: Smashing Swift
#47Earlier quoted context omitted.
Very interesting, thanks. I also ran up against another annoying bug/oversight/v0.1ism : You can't inherit from a generic class without becoming generic yourself. So, even if you fully instantiate your parent's type information, you have to be generic as well! For example: class Foo { ... } class Bar : Foo { ... } You'd expect Bar to be a non-generic type, but this throws a compiler error. You have to declare: class…
Well, derived classes are meant to be drop-in replacement for the base class. In that sense it totally makes sense that you can't have a non-generic child class of a generic base class. Otherwise it encourages design where classes are treated as method dumps.
The fact that an instance of A is assignment compatible with a location of type B does not imply that a class of type A is assignment compatible with a location of type class of B.
This is not the case for languages like C#, Java, C++ etc. (despite those languages not having class types); if a subclass does not define all the constructors of its ancestor class, the subclass is not a "drop-in replacement".
Delphi does have class value polymorphism that mirrors instance polymorphism, and it can be a source of confusion, not to mention type holes. For A inheriting from B, you can construct a value of type A using a constructor of B if you assign A to a location of type class of B; A's constructor won't run, and its assumptions and invariants won't necessarily hold. It's one of several problems that makes designing robust classes in Delphi awkward.
Re: Smashing Swift
#48Earlier quoted context omitted.
The language is not "innovative" as they claim, so people are expecting at least some learning from mistakes of prior languages. They could've hired some smart people from more software-oriented companies or something.
Given the constraints, it's certainly very innovative.
Re: Smashing Swift
#49Earlier quoted context omitted.
Very interesting, thanks. I also ran up against another annoying bug/oversight/v0.1ism : You can't inherit from a generic class without becoming generic yourself. So, even if you fully instantiate your parent's type information, you have to be generic as well! For example: class Foo { ... } class Bar : Foo { ... } You'd expect Bar to be a non-generic type, but this throws a compiler error. You have to declare: class…
Well, derived classes are meant to be drop-in replacement for the base class. In that sense it totally makes sense that you can't have a non-generic child class of a generic base class. Otherwise it encourages design where classes are treated as method dumps.
Indeed, calling it Bar seems really weird to me. Usually, in a declaration, the thing inside the angle brackets is a the name of a parameter, which can assume various values at runtime:
class Foo
But in the subclass, it's the name of a type: class Bar
Essentially, one is a declaration, and the other is an expression. Like and l-value and an r-value. I don't think i've ever seen a language which allows both of those in the same place.Re: Smashing Swift
#50I successfully got the Functor example to work like this: protocol Functor { typealias T typealias FunctorResult func map (mappingFunction: T -> P) -> FunctorResult } extension Dictionary : Functor { func map (mappingFunction: ValueType -> P) -> Dictionary { var newDict:Dictionary = [:] for (key, value) in self { newDict[key] = mappingFunction(value) } return newDict } }
The typical efficient implementation of a protocol (aka an interface) is a vtable - an array of pointers to functions. When you instantiate a generic in a statically compiled language, that usually clones the body of the generic thing (method or type) with references to the generic parameters replaced with the type arguments; and the new, cloned body is handed off to codegen.
But if you instantiate via a protocol reference, the compiler doesn't statically know the implementation of the thing you're trying to call - it can't see the body of code to clone. It's an indirect function call through a variable, and without a restricted language, analyzing it quickly runs into the halting problem.
With runtime code generation, the problem can be solved with sufficient magic - the runtime can rewrite as necessary. That's how .NET implements this.
Alternatively, if the body of each generic method is compiled using some form of dynamic dispatch - e.g. every operation on a value whose type is a generic parameter is done via an table of function pointers, and this table is passed into the generic method at the point of every call - then it can work, at some cost in speed. Haskell works like this, AIUI.
Java does it even more simply, with full-fat dynamic dispatch - all generic parameters turn into Object, and method bodies get runtime casts inserted as necessary.