[HN Gopher] Embedded Swift on the Raspberry Pi Pico
___________________________________________________________________
Embedded Swift on the Raspberry Pi Pico
Author : goranmoomin
Score : 278 points
Date : 2024-03-06 01:10 UTC (21 hours ago)
(HTM) web link (forums.swift.org)
(TXT) w3m dump (forums.swift.org)
| RetpolineDrama wrote:
| Super cool! I absolutely adore swift, it has so many simple
| features I love that I am sometimes surprised to find are missing
| in other languages. (ex off the top of my head: switching on
| enum's with associated values is super powerful in Swift and I
| was surprised Dart was completely missing that when I tried
| flutter a while back?)
|
| Ex:
|
| enum MyEnum<T> { case one case
| two(twosChild: Child) case three(threesGenericChild:
| T) case four(foursCallbackChild: () -> Void)
|
| }
|
| You can then pass this enum around and switch on it, with
| compiler-guaranteed completeness everywhere in your codebase. It
| seems so freaking simple, but it's incredibly useful.
| refulgentis wrote:
| Dart has it, last 12 months or so.
|
| Funnily enough, I sort of had the opposite journey, Swift seems
| horribly complicated and over-specified. The Dart compiler
| knows if I do a null-check, it can treat following references
| as safe, instead of if let x = x etc.
|
| And it just hasn't lived up to any of the initial starry-eyed
| hype I had for it and expectations for a wider Swift
| ecosystem...
|
| Like, here, it's great it runs on Raspberry Pi Pico but...it
| can't render UI unless someone writes a new UI library from
| scratch. And whoever does that inevitably will have to copy
| SwiftUI directly or alienate the people who actually know
| Swift.
| marcellus23 wrote:
| > Swift seems horribly complicated and over-specified. The
| Dart compiler knows if I do a null-check, it can treat
| following references as safe, instead of if let x = x etc.
|
| `if let x = x` is an alternative to a null check, it's not as
| if now you need both a null check and an `if let`. What makes
| an `if let` more complicated?
| refulgentis wrote:
| There are now 2x as many syntaxes for the same operation,
| if let and if != null
| RetpolineDrama wrote:
| It's not the same op though. One is a check, the other
| creates an in-context copy that's unwrapped from the
| optional. The compiler of course optimizes this out but
| it's not the same.
| refulgentis wrote:
| Right. In Dart they are the same. In Swift they are
| distinct.
| mckn1ght wrote:
| They have different use cases. if x != nil is to do some
| work without needing x, because you'd still have to
| unwrap it if you used it.
|
| That's what if let y = x is for, it creates a safe
| lexical context to use the unwrapped value.
|
| And then you have guard let y = x which is a stronger
| guarantee that no code further down in the context is
| executed if x is nil. This helps to write happy-path code
| with early returns, avoiding pyramids of doom and
| encouraging writing code where all the assumptions are
| listed up front with logic handling exceptional cases
| before finally arriving at the logic that works under all
| the assumptions.
|
| Dart feels like a step backwards after seeing the
| benefits these provide.
| afavour wrote:
| > They have different use cases.
|
| But there's also no harm in combining them. I agree with
| the OP, TypeScript does what they describe Dart doing and
| I find it much simpler than the way Swift does it. It's
| never confusing.
| mckn1ght wrote:
| > But there's also no harm in combining them
|
| Disagree. I've seen people write things like the
| following: if x != nil { x!.foo() }
|
| and then later the x != nil condition is changed to no
| longer check for nil, or the x!.foo() is moved out of
| that lexical scope elsewhere, or copypastad, and then the
| force unwrap crashed. I've seen similar yet more subtle
| bugs with soft unwraps instead of forced: x?.foo()
|
| Not possible if you use if let y = x . If you copypasta
| the inner scope with the different variable name then it
| won't compile.
|
| (ofc these are trivial representative examples, in
| reality these were lexical scopes with many lines and
| more complicated code)
|
| It's not just about how the code looks when you write it,
| it's the paths that can be taken by future maintenance
| programmers.
|
| I've complained about the large surface area of swift
| syntax, stdlib etc in the past, but I don't personally
| find this specific thing confusing.
| refulgentis wrote:
| For removing the null check, that, of course, would cause
| a compiler error.
|
| For moving the force unwrapped out of the if, that's a
| problem with force unwrapping, not combining the
| syntaxes.
| saagarjha wrote:
| Changing the type of something based on a conditional
| check is not great, because if I wanted a non-optional I
| would request it. Sometimes a nil check is literally just
| a nil check. What if I want to set the value back to nil
| if it is not-nil? Why should I have to wrap things back
| in an optional if I want to pass it along as such?
| mraleph wrote:
| The reason why languages promote variable types based on
| control flow is because developers en masse actually
| expect that to happen, e.g. facing the code like
| Dog? maybeDog; if (maybeDog != null) {
| maybeDog.bark(); }
|
| If compiler says "sorry, maybeDog might be null",
| developer (rightfully so) usually responds "but I have
| just checked and I _know_ it is _not_ , why do you bother
| me?". So languages chose to accommodate this.
|
| _> What if I want to set the value back to nil if it is
| not-nil?_
|
| You can. The type of the variable does not actually
| change. You could say that the information about more
| precise type is simply propagated to the uses which are
| guarded by the control flow. The following will compile
| just fine: Dog? maybeDog; if
| (maybeDog != null) { maybeDog.bark();
| maybeDog = null; }
|
| _> Why should I have to wrap things back in an optional
| if I want to pass it along as such?_
|
| You don't, with a few exceptions. There is a subtype
| relationship between T and T?: T <: T?, so the following
| is just fine: void foo(Dog? maybeDog);
| Dog? maybeDog; if (maybeDog != null) {
| maybeDog.bark(); foo(maybeDog); // Dog can be
| used where Dog? is expected }
|
| You might need to account for it in places where type
| inference infers type which is too precise, e.g.
| Dog? maybeDog; if (maybeDog != null) {
| // This will be List<Dog> rather than List<Dog?>.
| final listOfDogs = [maybeDog]; }
|
| Though I don't think it is that bad of a problem in
| practice.
| saagarjha wrote:
| See, I _don 't_ think languages should accommodate this,
| because I see it as an ugly solution. It's nice that it
| works in a few cases but then it very quickly breaks
| down: a developer finds that their null check is enough
| to strip an optional, but a test against zero doesn't
| convert their signed integer to unsigned. Checking that a
| collection has elements in it doesn't magically turn it
| into a "NonEmptyCollection" with guaranteed first and
| last elements. I'm all for compilers getting smarter to
| help do what programmers expect, but when they can't do a
| very good job I don't find the tradeoff to be very
| appealing. Basically, I think pattern matching is a much
| better solution this problem, rather than repurposing
| syntax that technically means something else (even though
| 90% of the time people who reach for it mean to do the
| other thing).
|
| Also, fwiw, I was mostly talking about things like the
| last example you gave. I guess it would be possible that
| in circumstances where T is invalid but T? would be
| valid, the language actually silently undos the
| refinement to make that code work. However, I am not sure
| this is actually a positive, and it doesn't help with the
| ambiguous cases anyways.
| refulgentis wrote:
| This is the elegant solution.
|
| Where does it break down?
|
| This isn't the same thing as "magically" changing the
| type.
|
| What does the syntax technically mean?
|
| What refinement is undone?
|
| I think you're a bit too wedded to the idea that there's
| a type conversion going on or some dark magic or
| something behind the scenes that's "done" then "undone"
| like a mechanism. There isn't. It's just static analysis.
| Same as: let x: Animal; x =
| Dog() if (x is Dog) { x.bark()
| }
|
| The Zen koan you want to ponder on your end is, why do
| you want to A) eliminate polymorphism from OOP B) remove
| the safety of a compiler error if the code is changed to
| x = Cat()?
| saagarjha wrote:
| I don't like that either. x is Dog is a boolean
| expression. Presumably I can write let
| isDog = x is Dog;
|
| And the value whether it is a dog or not goes into that
| new variable. The fact that I can't then immediately go
| if (isDog) { x.bark() }
|
| shows the deficiencies of this static analysis (even if
| you _could_ do some simple value tracking to make this
| work, it doesn't really address the real issue I have
| with it, which I described above: why can't I do this
| refinement for other things?) The conceptual model is one
| of "we special cased 2-3 cases that we can detect", which
| I don't find very elegant, especially considering that
| other languages seem to have better solutions that
| express the operation in what I feel is a better way.
|
| (The equivalent Swift code would be something like this:
| let x = Animal() if let dog = x as? Dog {
| dog.bark() }
|
| I see this as much superior. One, because x is still
| available in the scope of I want an Animal and not a Dog
| for whatever reason. I understand that most of the time
| you don't do this but to have it available and not have
| to do a special case for it is nice. The second thing is
| that I just like the syntax, since it gives you an
| opportunity to give a more specific name in that branch
| as part of the assignment. Third, it composes, because
| none of the operations are special save for the "if let"
| binding. This code is also valid: let x =
| Animal() let dog /* : Dog? */ = x as? Dog if
| let dog /* = dog */ { }
|
| The static analysis for undoing polymorphism is the exact
| same as the one for binding to optionals, because the
| idiomatic way to cast results in an optional.)
| troupo wrote:
| I don't think any of that has to do anything with static
| analysis deficiencies. The analysis is the same. What
| Swift requires is for the user to manually help the
| compiler with a rather verbose and otherwise unnecessary
| construct.
|
| Type narrowing is not a new idea
| saagarjha wrote:
| It's not a new idea, but I don't think it's a _good_
| idea. That's just it. Swift has a construct to do the
| equivalent and it's fewer characters to boot when
| compared to Dart when you're going from an optional to
| non-optional type.
| troupo wrote:
| But that's exactly what Swift does: it narrows the types.
| To do that, it uses a separate construct that only exists
| to make the parser ever so slightly simpler.
| mraleph wrote:
| > The fact that I can't then immediately go
|
| Who said you can't? :) This actually works in Dart:
| Dog? dog; bool isDog = dog is Dog;
| if (isDog) { dog.bark(); }
|
| i.e. boolean variables which serve as witnesses for type
| judgements are integrated into promotion machinery.
|
| I do agree with you that
|
| 1. In general there is no limit to developers'
| expectations with respect to promotion, but there is a
| limit to what compiler can reasonably achieve. At some
| point rules become too complex for developers to
| understand and rely upon. 2. Creating local variables
| when you need to refine the type is conceptually simpler
| and more explicit, both for language designers, language
| developers and language users.
|
| I don't hate excessive typing, especially where it helps
| to keep things simple and readable - so I would not be
| against a language that does not do any control flow
| based variable type promotion. Alas many developers don't
| share this view of the world and are vehemently opposed
| to typing anything they believe compiler can already
| infer.
|
| It's all a matter of personal taste in the end.
| troupo wrote:
| The ugly solution is Swift's if let x = x which is
| literally the same check, but in a more verbose manner.
|
| Yes, compilers should be able to help in this and many
| other cases, and not just give up and force the
| programmer to do all the unnecessary manual work
| saagarjha wrote:
| It's not a check, it's binding a new variable with a
| different type (which may or may not have the same name;
| if it does you can use if let x these days). And solving
| the other examples I mentioned is generally out of the
| realm of most programming languages in use today (except
| maybe TypeScript?) It comes with significant challenges
| that I'm not sure we are ready to address properly yet.
| teho wrote:
| In Dart if you want to narrow down a nullable final class
| variable, it is not enough to do
|
| if (value == null) { // value is still nullable here }
|
| instead you need to first capture the value
|
| final value = this.value if (value == null) { // value is
| non-null }
|
| Swift's guard and if let syntax seems way nicer here. In
| swift, it's also nice to destructure nested nullable
| values using if let.
|
| if let value = object.object?.value { // value is non
| null }
|
| In dart you'd need to first assign this into a local
| variable and then do the null check which is
| unnecessarily verbose.
| mraleph wrote:
| In Dart 3 instead of declaring the variable and then
| comparing you can simply write an if-case pattern:
| if (value case final value?) { // value is a
| fresh final variable }
| teho wrote:
| The more you know, I had totally missed this.
| Someone wrote:
| So Dart is moving in the Swift direction, which has
| if let value = value { // a new binding named
| 'value' refers to value, unwrapped }
|
| or (newer syntax that I initially found even weirder than
| the older one, but both grew on me) if
| let value { // a new binding named 'value'
| refers to value, unwrapped }
|
| (The old version will remain, as it is more flexible,
| allowing such things as if let baz =
| foo.bar(42) { // a new binding named 'baz'
| refers to foo.bar(42), unwrapped } )
| secretsatan wrote:
| Small change made in swift means an unwrap can just be
|
| `if let x { }`
|
| Which while small, is great if you do it all the time.
|
| Swift though made me question how much I used optionals,
| now I get annoyed if they're over used, it usually means
| someone down the line has not made a decision, they
| propagate through the program and eventually someone
| wonders why they didn't get a value.
|
| I like the Result type and the Flexibility of the Enums a
| lot for this
| RetpolineDrama wrote:
| >Dart has it, last 12 months or so.
|
| To clarify, in the above scenario in dart I can have an input
| with type MyEnum and do this?
|
| switch myEnum {
|
| case let one: // react to this here
| case let two(twosChild: twosChild): // call an
| API passing in a child element of twosChild here
| case let three(threesGenericChild: threesGenericChild):
| // T: Protocol, and call an extension function
| threesGenericChild.extension() here? case let
| four(foursCallbackChild: foursCallbackChild): //
| Pass foursCallbackChild callback into another context, and
| execute an escaping closure if needed?
|
| }
|
| Last I checked Dart required a nested if/else tree and didn't
| have compiler-guarantees of switch completeness like the
| above.
| refulgentis wrote:
| Correct, Dart has enum exhaustiveness checks, associated
| types, and expressions as of 11-13 months ago:
| https://cfdevelop.medium.com/dart-switch-
| expressions-33145c3... (keeping it short and simple because
| I'm at -2 on the original post, don't want to look like I'm
| argumentative)
| mraleph wrote:
| In Dart 3 you have patterns and sealed class families to
| achieve that. See my comment above[1].
|
| The syntax is unfortunately more verbose, but if all goes
| well we will address that issue this year.
|
| [1]: https://news.ycombinator.com/item?id=39613415
| timsneath wrote:
| I believe Dart has pattern matching, but not associated
| values of different types.
| mraleph wrote:
| In Dart you use class hierarchies instead, rather than
| enums (which in Dart are way to define a compile time
| constant set of values). So the original example becomes:
| sealed class MySomething<T> { } final
| class One extends MySomething<Never> { }
| final class Two extends MySomething<Never> {
| final Child child; Two(this.child);
| } final class Three<T> extends MySomething<T>
| { final T value;
| Three(this.value); } final class Four
| extends MySomething<Never> { final int Function()
| callback; Four(this.callback); }
|
| And then you can exhaustively switch over values of
| MySomething: int foo(MySomething<String>
| foo) { return switch (foo) { One() =>
| 1, Two(child: Child(:final value)) => value,
| Three(:final value) => int.parse(value),
| Four(:final callback) => callback(), }; }
|
| The declaration of a sealed family is considerably more
| verbose than Swift - and I really would like[1] us to
| optimized things for the case when people often declare
| such families. Macros and a primary constructors will
| likely provide reprieve from this verbosity.
|
| But importantly it composes well with Dart's OOPy nature to
| achieve things which are not possible in Swift: you can mix
| and match pattern matching and classical virtual dispatch
| as you see fit. This, for example, means you can attach
| different virtual behavior to every member of the sealed
| class family.
|
| [1]: https://github.com/dart-lang/language/issues/3021
| jwells89 wrote:
| > And whoever does that inevitably will have to copy SwiftUI
| directly or alienate the people who actually know Swift.
|
| I may be wrong, but I don't think this is actually true.
| SwiftUI isn't universally loved in the community, largely
| thanks to its rough edges and how it struggles with that last
| 10% of polish in projects written with it. While copying
| SwiftUI wouldn't necessarily be wrong per se, you'd actually
| probably get more rapid buy-in by copying "boring" old
| imperative UIKit, as that's what most writers of Swift are
| using.
| refulgentis wrote:
| s/SwiftUI/UIKit, doesn't matter. (though I'm happy to have
| someone else point out SwiftUI has...some growing
| pains...it would have felt unfair for me to do so)
|
| Point is its DOA for UI on non-Apple platforms.
|
| Either you:
|
| - attract current Swift programmers and keep up with
| $APPLE_UI_FRAMEWORK with no assistance.*
|
| - attract no one and make a brand new framework in Swift.
|
| - bind to some other UI framework, alienate current Swift
| programmers*, get all the people who have been dying to
| write Swift yet didn't build a UI framework for 7 years
|
| There's just no universe where using Swift to write UI on
| non-Apple platforms makes sense to any constituency. You
| have to be simultaneously obsessed with Swift and don't
| care about platform-first UI, or want to maintain two
| separate UI frontends.
|
| I hate being that absolutist, but that is what 16 years of
| experience on Apple platforms has taught me.
|
| I'm surprised by the # of people arguing there's a
| possibility something else coudl work. I guess what I'd say
| is, if there is, where is it? Swift was on Linux eons ago,
| I believe before I started at Google so 7+ years.
|
| * People used to try this to do iOS/OSX cross-platform,
| those projects are dead. One could argue this is just
| because Catalyst exists. Sure, but, let's just say you need
| at least N / 2 engineers, where N = the number of engineers
| Apple has on an arbitrary UI framework, in order to keep up
| with it. That's a lot.
|
| ** I've been in Apple dev since iPhone OS 2.0, and while in
| theory this could work, in practice it doesn't. Ex. Qt
| won't appeal to Apple programmers. It's antithetical to
| community values.
| hgs3 wrote:
| > The Dart compiler knows if I do a null-check, it can treat
| following references as safe, instead of if let x = x etc.
|
| Does Dart bind a new variable 'x' for the if-statement scope
| or does the if-statement scope refer to the same 'x' from the
| outer scope?
|
| The reason Swift and other languages bind a new 'x' variable
| (if let x = x) is because the original 'x' can be assigned a
| different value elsewhere, like in another thread or a
| closure. If a closure captures and assigns null to 'x' and
| there is only one binding of 'x', then that means the 'x'
| within the if-statement will become null _post null-check_
| which is type unsound. I believe TypeScript has this
| "problem" as well.
| FuturisticGoo wrote:
| I assume Dart refers to the same variable since:
|
| 1) Dart doesn't have threads, it has isolates (where memory
| is not shared). So no variable modifications here.
|
| 2) Dart will promote a variable as not null after a non-
| null check only if it cannot be modified elsewhere, ie, the
| variable is final (can't be modified once assigned), or
| there's no other reference to it.
| KerrAvon wrote:
| gentle reminder that `if let x = x` can now be spelled
| simply `if let x` in current versions of Swift
| jwells89 wrote:
| Have been loving this feature. It's a small but impactful
| QoL improvement.
| fingerlocks wrote:
| > it can't render UI unless someone writes a new UI library
| from scratch
|
| This is true for literally every programming language. You
| can't render a UI, in general, without a target compatible UI
| library.
|
| SwiftUI and UIKit are specific Apple things built on top of
| CoreAnimation and completely separate from the Swift
| language. And swift will happily link to C and somewhat C++,
| so no it's not all evident why one would copy Apple's SDK to
| render UI on a completely separate platform and environment.
| jwells89 wrote:
| I miss Swift enums when writing Kotlin. Kotlin enums are more
| restricted in that associated values can't differ between
| cases, which limits their usefulness and means that much of the
| time what you want are instead sealed classes.
|
| There's actually several bits of Kotlin like this which feel
| somewhat pedantic/idiosyncratic and fussy if you're used to
| writing Swift. I'm sure there's valid design reasons behind
| these decisions, but sometimes it feels like unnecessary
| friction.
| MrBuddyCasino wrote:
| Since sealed class definitions can live in the same file and
| the syntax is quite compact, in Kotlin they don't annoy me as
| much as in Java.
| iknowstuff wrote:
| Yup it's called a sum type, or a tagged union
| https://en.wikipedia.org/wiki/Tagged_union
| bmitc wrote:
| The enum example is not really a union though or is a
| constrained version. For example, the cases are non-
| recursive.
| tialaramex wrote:
| Um, what? You believe unions are recursive data structures?
| bmitc wrote:
| Yes. For example, from Standard ML:
| datatype 'a list = nil | :: of 'a * 'a list
| tialaramex wrote:
| I have never seen this called a "union", and that's
| certainly not what people mean when they speak of a
| "tagged union".
| bmitc wrote:
| What do you think tagged unions are? What languages are
| you referring to?
|
| F# calls these discriminated unions. OCaml calls them
| variants or tagged unions.
|
| https://learn.microsoft.com/en-us/dotnet/fsharp/language-
| ref...
|
| https://ocaml.org/docs/basic-data-types#variants
| louthy wrote:
| It is exactly what they are. 'Tagged' or 'discriminated'
| unions are a set of named product types - the name being
| the tag/discriminator.
| adamwk wrote:
| Swifts enums can be recursive though as can rusts
| bmitc wrote:
| Thanks for the clarification. That does indeed make them
| closer to unions.
| hyperthesis wrote:
| https://wikipedia.org/wiki/Pattern_matching since 1957
|
| I feel ML is the most famous for it.
| bmitc wrote:
| As others have pointed out, that is actually a stunted and
| quite limited version of pattern matching that existed in other
| languages for years and even decades before Swift.
|
| F#, OCaml, and Standard ML are the primary examples. It's
| surprising to me how ignored these languages are.
| arwhatever wrote:
| Languages without this feature are basically refusing to wash
| their hands between the morgue and the maternity ward at this
| point.
| tialaramex wrote:
| [This is a reference to Ignaz Semmelweis, a Hungarian medic
| who wanted doctors to wash their hands properly based on
| his observations of the difference between the outcomes for
| women giving birth who were cared for by midwives (who
| don't work with corpses) and medical students (who do).
| This is very slightly before modern germ theory is
| established, so the doctors who reject Semmelweis'
| suggestions aren't strictly rejecting known facts about the
| world - Semmelweis can't explain _why_ it 's important to
| do this, only that it will work (which it does).]
| bmitc wrote:
| Thanks for explaining the reference! I was wondering
| about that as I had never heard that turn of phrase
| before. I looked him up and apparently he was put into an
| asylum due in part to his recommendations and the
| rejection of them and subsequently beat to death while
| committed. An absolutely brutal example of being
| persecuted for being right.
| wilg wrote:
| I don't think Swift's enum with associated values are pattern
| matching. You can use pattern matching to unpack them though.
| (https://docs.swift.org/swift-book/documentation/the-swift-
| pr...)
| bmitc wrote:
| Yea, I was sloppy with my language. But the point stands,
| and the unions are intrinsically tied to pattern matching.
| filleduchaos wrote:
| I don't really understand the point of pointing this out. The
| GP already says that it's a _simple_ feature that they 're
| also surprised isn't available in more languages - nowhere
| did they claim that Apple invented it or that it's a super
| innovative thing or anything.
| bmitc wrote:
| The commenter mentioned:
|
| > it has so many simple features I love that I am sometimes
| surprised to find are missing in other languages
|
| and a few other things that led me to believe they were
| unaware of discriminated unions. There was an implication
| that this was a unique or novel feature in Swift. It's like
| someone being excited about Python's pattern matching,
| thinking Python came up with it and wishing other languages
| had it when it's a watered down, less useful version of
| that found in languages it ignored for 30 years.
| filleduchaos wrote:
| I don't know, personally I think it is an immense leap of
| logic to look at someone's surprise that a simple feature
| is missing in [another] language and conclude that
| they're saying the feature is unique or novel.
| bmitc wrote:
| I don't know how else you interpret what I quoted.
|
| And it's not a judgement.
| filleduchaos wrote:
| Rust has a borrow checker. I think it is unique/novel,
| and I definitely don't think it is simple. In fact, it's
| precisely _because_ I think it is unique /novel that I
| very much am not surprised that it doesn't exist in other
| languages that I use. Why on earth would I be surprised
| that a feature I think was just invented isn't yet
| present in other things? That's not how the passage of
| time works.
|
| On the other hand, Rust also has first-class functions
| including closures. I _do_ think that closures are a
| simple programming language feature, and I 'm definitely
| surprised/put off when I write a language that doesn't
| have them (though these days I'm not sure there are any
| mainstream ones, now that Java and C++ both have them in
| the spec). Again it's precisely because I think of
| closures as the _opposite_ of unique /novel that I am
| surprised at their absence. Why would I be surprised that
| a language does not have closures if I thought the Rust
| team just made them up?
|
| So yes, I have no idea how one would conclude that
| someone's surprise at a simple feature being unavailable
| indicates that they think the feature is unique or novel,
| other than just being a knee-jerk reaction.
| freedomben wrote:
| > _are missing in other languages_
|
| GP is probably talking about other mainstream languages
| or language that they regularly use such as
| javascript/typescript. It makes no sense to interpret
| this as "are missing in every other language ever
| invented."
|
| You're right that plenty of people do ascribe Apple
| credit for inventions that they didn't invent, but there
| isn't enough context/detail here to conclude that has
| happened in this case.
| bmitc wrote:
| We're in the weeds here, but I actually think it was the
| other commenter responding to me that was under that
| impression. I didn't interpret the original comment as
| saying it wasn't in any other language ever. There are
| all sorts of niche languages that do things in very
| interesting and novel ways. I just consider F#, OCaml,
| and Standard ML as mainstream-ish languages. They're just
| poorly known, despite their influences on languages,
| although those influences are still not as strong as they
| should be.
|
| I know this sounds very Emacs-fanatic of me, but it does
| get a bit tiring in the software world to have spent a
| lot of time in tool and language discovery only to be
| forced to work in a language that feels like a step
| backwards where people suddenly get excited or finally
| acknowledge the benefits of language designs that came
| before them. Really, this primarily reflects on Python,
| which I am currently having to use, and it feels like
| several step-functions down in capability, robustness,
| clean-ness, and several other qualitative and
| quantitative factors compared to something like F# and
| OCaml. There's a huge amount of "let's ignore other
| languages but then ad-hoc reinvent what they do in a
| mudball type of fashion". See Python's concurrency story
| for a particular egregious example. I am constantly
| bitten by things in Python that I'm honestly aware of _no
| other language_ doing.
|
| So it's probably fair to say I read in a bit to the above
| comment. I'm happy either way that people are
| appreciating ML-like features.
| freedomben wrote:
| I could not agree more! Python in particular, is so
| painful to work in, and the addition of insult to injury
| of other Python people definitely gets under my skin. I
| think one of the most disappointing realizations I've had
| is the truth in "the best product doesn't win," which is
| especially apparent when it comes to programming
| languages.
|
| I've been doing Elixir for several years and have tried
| to get others excited about it, and the frustrating
| chicken and egg problem of "there's not a good pool of
| programmers to hire or ecosystem of libraries" often
| seems to kill it in its tracks. Especially painful when
| it comes to machine learning where Python has de-facto
| won.
| nozzlegear wrote:
| F# is my "primary" programming language, I work with it daily
| and absolutely love it. That said, it doesn't surprise me
| that people ignore it or don't know about it given
| Microsoft's own lack of attention and focus on it. Half the
| time it seems new dotnet features aren't even compatible with
| F#.
|
| The day C# gets discriminated union types and true exhaustive
| pattern matching is the day I'll have to think long and hard
| about how much more time I want to put into working with my
| beloved F#.
| Gibbon1 wrote:
| I strongly believe (waves hands while making incoherent
| small brained primate noises) that discriminated union
| types would be fabo for C as well.
|
| Example why it would be sweet. Compiler could spit out a
| warning if it's not sure the correct union type is being
| used. Like if the pet union has dog and cat. Cat has
| respawn set initially to 9. Dog doesn't have respawn. If
| you try to set respawn without checking if it's a cat
| compiler whines about it.
| adamwk wrote:
| How is it stunted or limited?
| jsheard wrote:
| How usable/useful is Swift on not-Apple platforms in general
| nowadays? I've been giving it a wide berth since I got the
| impression that other platforms were more of an afterthought, but
| maybe things have improved when I wasn't looking.
| pdpi wrote:
| I've been playing around with Swift on Windows, building a
| small raylib-based game. The only raylib bindings out there are
| pretty outdated so I had to write my own, with little to no
| experience with either C or Swift. It was _way_ easier to get
| that set up than I expected it to be!
|
| The language server seems a bit clunky on Windows, I've only
| used Swift with Xcode on macOS so I don't know if that's
| platform specific.
| zer0zzz wrote:
| The arc browser has a beta for windows. It's pretty decent so
| far and is written in swift
| mpweiher wrote:
| It's based on Chromium, wich is C++. In terms of total code,
| I'd wager it's around 99% C++.
| machinekob wrote:
| I think he means GUI not engine as they are indeed just
| using chromium engine as browser.
| zer0zzz wrote:
| Yes. Ignoring the engine there's a lot of swift in how
| they build the ui components and sync tabs etc. they've
| built something similar to SwiftUI but it used winui/wpf
| (or whatever it's called these days ) underneath.
| lukeh wrote:
| It's pretty usable on Linux, the odd package needs a patch, but
| it's pretty smooth sailing. Of course, if you're trying to
| write an application with a UI, YMMV (although swift-cross-ui
| looks promising).
| hboon wrote:
| There's https://speakinginswift.substack.com/p/swift-meet-winrt
| shagie wrote:
| IBM was working on it for a while...
|
| IBM Stops Work on Swift -- Q&A with Chris Bailey ::
| https://www.infoq.com/news/2020/01/ibm-stop-work-swift-serve...
| ( 43 points | 3 comments
| https://news.ycombinator.com/item?id=22175652 )
|
| In this (and highlighted in a comment) there's a quote:
|
| > Swift benefits greatly from being an embedded part of Apple's
| ecosystem, but it also provides challenges for its organic
| growth as there's a lot of dependency on Apple for capabilities
| that the server ecosystem requires. For example, almost all
| Swift developers use Apple's Xcode as their IDE and it has
| fantastic support for developing for iOS devices, including the
| ability to run locally in emulator environments. It would be
| great to add support for writing server code that allows
| developers to develop directly into containerized environments
| from their local IDE by supporting the simple integration into
| Xcode of development tools such as Appsody. Where there is open
| governance and open ecosystems, it enables the community to
| contribute and to solve the problems and use cases that are
| important to them.
|
| Same timeframe: IBM Stops Server Side Swift Framework
| Development - https://news.ycombinator.com/item?id=21808619
| (156 points | 97 comments)
|
| ---
|
| From earlier times:
|
| Introducing the IBM Swift Sandbox -
| https://news.ycombinator.com/item?id=10676655 (246 points | 59
| comments)
|
| IBM says Swift is ready for the enterprise -
| https://news.ycombinator.com/item?id=12581250 (176 points| 226
| comments)
| lukeh wrote:
| I use vim on Linux without any LSP integration, it's fine,
| although I do prefer Xcode. I guess I should look into
| VSCode...
| freedomben wrote:
| If you're a vim user, you're gonna find vscode close enough
| that it feels like you're close, but far enough that it's
| frustrating. I finally setup coc and have been quite happy.
| frizlab wrote:
| I'm using swift on the server with vapor and it's really
| working great. Non-Apple platforms support has been greatly
| enhanced over time and is still being enhanced.
| navanchauhan wrote:
| I like using it for non-GUI programs.
|
| I usually test them on a Linux VM and a Raspberry Pi
| TravelPiglet wrote:
| It's barely usable on Apple platforms. Horrible compiler and
| Xcode is very buggy. Segfaults and error report dialog popups.
| jwells89 wrote:
| Xcode is fine as long as you don't have a ton of Obj-C -
| Swift bridging going on and avoid XIBs/Storyboards, with
| writing UIKit in pure code being the most stable option
| (SwiftUI still needs some time in the oven). Writing
| idiomatic Swift also helps (code smells like deeply nested
| closures can make SourceKit grumpy).
|
| I've spent countless hours working in it and crashes and
| errors have been rare for years now. Especially since
| ditching CocoaPods in favor of Swift Package Manager for
| dependencies, I've found that Android development to be
| considerably more frustrating with the mess of Gradle and
| Proguard paired with the surprisingly anemic Android
| Framework. Jetpack Compose is thankfully replacing Android
| Framework and is a major improvement, but from time to time
| Gradle and Proguard make me want to tear my hair out.
| chairhairair wrote:
| That first paragraph is hilarious and consistent with my
| experience.
|
| It's pretty baffling how bad Xcode is. Although at this
| point I'm not sure to what extent Swift is to blame.
|
| Everything seems to work much better when Swift is
| abandoned and I just use UIKit.
|
| (And it's a personal blessing when I get to use Flutter and
| bypass 90% of the insanity that is modern native iOS and
| Android dev)
| jwells89 wrote:
| It makes sense that UIKit is more solid, because not only
| does it have 17 years of its own history, but builds upon
| the legacy of AppKit which stretches back another 20
| years. By comparison SwiftUI is still quite young.
|
| Haven't touched Flutter because Material Design feels
| weird on iOS, its Cupertino theme isn't great, and I'm
| not the type to reinvent the wheel on UI design in the
| apps I work on. Also don't really feel like picking up a
| language, toolchain, and ecosystem for a single UI
| framework.
| mpweiher wrote:
| NeXTstep/AppKit was more solid in 1991.
| andrekandre wrote:
| whats your opinion on modern appkit vs back then?
|
| i may be crazy but even now i sometimes feel like appkit
| today is still more solid and less buggy than even
| uikit...
| the_gipsy wrote:
| I briefly worked on a swift app that had just a login
| screen and a background process, so no Storyboard stuff. It
| was still so horribly, horribly buggy, it starts getting
| comical. When turning to seasoned full-time iOS developers,
| they would just shrug it off as a normal thing. It
| constantly needs to be restarted, and actions retried. An
| insane amount of "clicking around". It was a complete joke,
| I cannot fathom that some people just take it as state of
| the art.
|
| I tried the IntelliJ IDE, which didn't feel so shoddy, but
| in turn has a lot of other problems that boil down to not
| being the "blessed" solution.
| jwells89 wrote:
| It's not that I'm shrugging bugginess off, I legitimately
| am not encountering these things. I restart Xcode maybe
| once every 1-2 weeks, if that. Maybe I've just learned
| how to not anger it?
|
| Android Studio (IntelliJ) on the other hand I've run into
| mysterious things with fairly frequently, like it failing
| to install the app on the connected phone after hitting
| run for no reason or builds failing with bogus errors,
| requiring a project clean to fix. Its "smart" refactoring
| tools also can't always be trusted to do the right thing,
| at least where XML UI layout files are concerned.
| lawgimenez wrote:
| We just started migrating our app to Jetpack after
| migrating our iOS to SwiftUI, so far Jetpack has been more
| fun. The problem is just the horrible Android documentation
| and starter tutorial which it is more video centric, I hate
| it.
| KerrAvon wrote:
| Have you used it recently? It's improved a lot in the last
| five years.
| w10-1 wrote:
| The automatic C/C++ bridging got way better in 5.9, so building
| an app integrating native libraries is pretty easy (~ 1 day to
| start iterating).
|
| As for Swift libraries, Stdlib is fully ported, Foundation can
| be spotty, the new Foundation-Essentials is small but growing.
| Swift-System has portable low-level path and such, and Shwift
| helps with fully async scripting.
|
| As for supported platforms, Ubuntu seems robust, AWS is usable
| but marginal. Windows has some hurdles - technical, legal, and
| incentives - but VSCode support seems relatively good for non-
| GUI stuff outside windows API's.
|
| Embedded has been landing in the main compiler and pushed by
| the Swift team lead. They're still issue-spotting, planning how
| (much) to live without a heap and the runtime metadata used for
| protocols, but the number of issues seems manageable for the
| intensity of effort, even though it's not Apple's priority.
|
| With Swift 6.0, a breaking release, up next (in September?),
| it's likely embedded features could be both driven by the
| desire to make any breaking changes now, and blocked by other
| priorities.
| georgelyon wrote:
| Great summary!
|
| One addition: Swift WASM support has recently become stable
| enough to be [included in
| CI](https://forums.swift.org/t/stdlib-and-runtime-tests-for-
| wasm...). The folks working on that have done a great job and
| I'm very excited for that to get more fleshed out!
| bsaul wrote:
| Depends on the platform. Android is still super rough (expect
| debugging custom third-party experimental compiler build
| scripts).
|
| Linux support is i think a bit better. But for now it's still
| the biggest handicap for the language for sure. Any sane
| project would have solved those issues a long time ago. But
| since it's an apple language, they seem to not be caring much.
| RantyDave wrote:
| FWIW Micropython look to be solving the "no drivers" problem by
| building a port that targets Zephyr.
| https://docs.micropython.org/en/latest/zephyr/general.html
| zoecarver wrote:
| Because of C/C++ interop, and integration with CMake, you can
| just add Swift to a Zephyr project and it pretty much Just
| Works. [The docs](https://github.com/apple/swift/blob/main/docs
| /EmbeddedSwift/...) should mostly apply to the Zephyr SDK as
| well.
| RantyDave wrote:
| Oh look at that, right in the repo. The Apple one. Wow.
| FlyingSnake wrote:
| Swift is really an underrated language mainly due to the Apple
| baggage. It hits the sweet spot between Rust and C++ due to it's
| sane design choices like structured concurrency or simple things
| like tagged enums, Result<T,E> etc.
|
| I wish it gains more popularity outside Apple land and is
| discussed more like Zig or Rust.
| slekker wrote:
| Wasn't the performance and tooling poor in Linux and Windows?
| Has something changed there?
| saagarjha wrote:
| Things are changing slowly.
| machinekob wrote:
| Linux is very much ok at least x64 vscode is working faster
| than Mac version but ofc. It is not Xcode
| sgt wrote:
| Having written a bit of Swift code on macOS and a bit for iOS,
| I agree. This language has a very nice flow to it which should
| appeal to developers. It's hard to explain, but somehow the
| language is a joy to work in (Xcode also helps with that
| experience, of course).
|
| If I could use a minimized Swift on embedded, I'd be very
| happy. Right now I'm just doing C for ESP32 and that sort of
| thing.
| FlyingSnake wrote:
| If you can like it despite using Xcode, then it means the
| language is really good.
| WanderPanda wrote:
| Yeah I was wondering the same! I fondly remember coding
| swift almost 10 years ago but large part of it was the good
| integration with Xcode I believe. Seems like they have an
| OSS LSP so probably that experience translates to other
| IDEs nowadays
| FlyingSnake wrote:
| > Coding swift almost 10 years ago.
|
| Umm... Swift was released 9 years ago
| southwesterly wrote:
| Which is 'almost' 10 years ago?
| the_gipsy wrote:
| That's never gonna happen.
| graemep wrote:
| It looks like a nice language but my concern would be Apple
| might decide not to support it on other platforms at some
| point. Just too dependant in a single company.
| Razengan wrote:
| It's literally open source bruh.
| pjmlp wrote:
| A language is an ecosystem, not only a CLI compiler.
| jocaal wrote:
| It scares me how many people don't realize this. A
| language is only as good as the things it allows you to
| build. Swift can be a great language from a PLT
| perspective, but it is pretty much only good at making
| apple UI's. Anything else and you are making some
| important compromises you might not be aware of.
| filleduchaos wrote:
| There are lots of other things Swift is good at.
|
| What important compromises are being made that aren't
| "libraries may not exist", which is true of any of the
| equally niche languages that get a lot more love because
| they aren't associated with Apple? Even the severely
| limited ecosystem is mitigated by the language having
| excellent C and decent-enough C++ interop.
| pjmlp wrote:
| That theory works well in vacum, not when there are
| languages with similar features and mature ecosystems to
| chose from.
|
| Microsoft is discovering how hard it is to take .NET
| outside Windows, the fierce competition of UNIX first
| programming language ecosystems, and Apple is not doing
| with Swift half as much as Microsoft is trying to.
| jwells89 wrote:
| Microsoft has a lot of baggage they're dragging around,
| though.
|
| Getting started on C# and Windows App SDK sucks a lot for
| example, because everything you google about them returns
| boatloads of results for myriad incarnations of C#, .NET,
| and XAML-based UI frameworks which makes figuring it all
| out somewhat painful.
| pjmlp wrote:
| Compared to that, Swift offers a CLI compiler, half
| working debugging and VSCode experience, and zero
| libraries.
|
| I bet very few of these work on Linux,
| https://swiftpackageindex.com/
| jwells89 wrote:
| That's certainly a valid weakness, but at least getting
| up and running on Swift's most native platforms is
| straightforward. One wouldn't expect C# and Windows App
| SDK on Windows to be as much of a struggle as it is.
| neonsunset wrote:
| The two are completely separate. Getting C# to build and
| run only needs executing 'winget install dotnet-sdk-8' on
| windows or 'sudo apt-get install -y dotnet-sdk-8.0' on
| e.g. Ubuntu.
| pjmlp wrote:
| I don't get why you're so down on WinAppSDK, something
| that is largely ignored by .NET developers, and is really
| only used by Windows team or those poor souls that still
| believe WinRT has a future.
|
| ASP.NET, EF, Avalonia, Uno, Akka.NET, Silk.NET, Unity,
| Godot and tons of other software packages work just fine
| on macOS and Linux, with JetBrains Rider and VSCode/C#
| Dev Kit/Ionide.
| jwells89 wrote:
| I like to develop in platforms' "preferred" frameworks
| when possible and am not really interested in solutions
| trying to be a "silver bullet". In the case of Windows I
| find the design language of Win11 actually pretty nice
| and would like to have that, which involves using
| WinUI/App SDK. There are alternatives such as writing an
| app with some other framework using a third party theme,
| but that can instantly become outdated with a system
| update or comes with weirdness like how some of the older
| Windows C#/XAML stuff gets all stuttery on displays
| running a refresh rates over 60hz.
| pjmlp wrote:
| That has nothing to do with cross platform .NET, and as
| mentioned only Redmond cares about it, and not everyone,
| Office team doesn't want anything to do with it, rather
| shipping Web tech on Windows.
|
| And despite all of this, Swift is a toy on Linux compared
| with .NET ecosystem on Linux.
| filleduchaos wrote:
| The sentiment I was responding to was that Swift is only
| good for making Apple UIs, which is patently false.
|
| Again, newer languages having less of an ecosystem than
| older languages is not news or somehow unique to Apple
| (or Microsoft by that matter). The existence of more
| mature languages than whichever one you're considering is
| not news - if it was, then nobody would start any project
| in anything other than like three languages. _And_ as I
| mentioned there is a _gigantic_ ecosystem that Swift and
| several others have access to by design, which for some
| reason people refuse to acknowledge whenever they shut
| down newer languages with "but no ecosystem".
|
| > Microsoft is discovering how hard it is to take .NET
| outside Windows
|
| Ten years ago you would have had a point. However it's
| 2024 and .NET is solid, stable, and widely deployed on
| Linux et al - and that's without taking projects like
| Unity into account. That's _far_ from only working well
| in a vacuum.
| graemep wrote:
| That is only a guarantee if there are other people who are
| willing to continue development if Apple stops.
|
| What if Apple stops development on other platforms, or
| makes future development proprietary who is going to
| maintain it for other platforms?
| BoxOfRain wrote:
| Yeah I played around with it a bit and I really like it, but
| I've never really had a reason to use it professionally since
| I'm mostly targetting Linux and as you say it's definitely seen
| as being a bit exclusive to Apple land.
|
| Can't complain though my current daily driver is Scala and
| that's also a fantastic language to work with.
| hardwaresofton wrote:
| Could you give some examples on where you feel Swift shines
| compared to Rust? I quite like Rust and it's associated tooling
| and type system.
| filleduchaos wrote:
| In my experience it has a solid 90+% of the semantic
| expressiveness - ADTs, advanced pattern matching, if
| statements and similar being expressions, traits (split into
| "protocols" and "extensions" in Swift), automatic reference
| counting, a well-defined ownership model (albeit not quite as
| strict as Rust's), constructs to prevent data races, etc. It
| lacks things like explicit control over lifetimes, and also
| defaults to copy-on-write rather than to move semantics -
| that isn't _unsafe_ , but it does lead to beginners writing
| programs that compile fine but behave in a way that's
| surprising to them. It also doesn't expose threads directly
| (similar to Go only having goroutines), but the concurrency
| model is quite nice to use. The language is obviously
| opinionated about its async runtime (Grand Central Dispatch,
| which is also available on Windows and Linux) so you don't
| have to wrangle with that yourself though of course it loses
| the power and flexibility of bringing your own.
|
| On the flip side, Swift provides a _lot_ of syntactic sugar
| that makes it feel faster /smoother to engage with than Rust.
| For example, enum literals don't have to specify the enum's
| name wherever their type can be inferred by the compiler. So
| e.g. when you are pattern matching on an enum value, the
| match arm `MyEnum::Red => {}` in Rust would just be `case
| .Red:` in Swift. It isn't much on its own, but each tiny QoL
| thing like this adds up.
| jwells89 wrote:
| Swift's syntax I think also makes it more approachable for
| people coming from other languages. Rust by contrast is
| rather intimidating looking for anybody without a
| background in C++.
| hardwaresofton wrote:
| Thanks for the feedback here -- this definitely make sense.
| Interested in the copy-on-write vs move semantics... I'm so
| used to it now that I almost prefer the harder/more manual
| control/checking that Rust provides, but I definitely see
| the ergonomics of going another way.
|
| I find Rust a bit easier for me to read, quite preference-
| driven as I prefer snake_case to camelCase but that's a
| tiny thing.
|
| And weirdly enough I think I actually prefer `MyEnum::Red
| => {}`, but maybe that's just stockholm syndrome.
|
| Excited to give Swift a try sometime soon.
| georgelyon wrote:
| It is a little out of date but a few years back I wrote up a
| few key differences: https://gist.github.com/GeorgeLyon/c7b07
| 923f7a800674bc9745ae...
| hardwaresofton wrote:
| Thanks for this list!
|
| > No macros / build-time code generation
|
| While I do appreciate macros, and use them sparingly I find
| the best case for them is doing things like generating
| to/from <protocol> (e.g. JSON) implementations.
|
| In Haskell, there's a fully baked system for derivation
| where you can set up implementations that walk the type
| trees, but most other languages don't have that -- I find
| macros to be a great slightly lower complexity way to do
| this kind of thing.
|
| What is Swift's answer in production? Does everyone just
| write extensions for their types? Rust's serde is a joy to
| use and 99% of the time "just works", despite the macro
| magic.
|
| > Type system function resolution
|
| I'm not sure this is a real problem for me or most people,
| but taken with the point about polymorphism (I guess this
| point is basically about late binding), I see the benefit
| here.
|
| > Protocols vs Traits as implemented
|
| Generic methods being allowed in Swift is quite nice.
|
| > Sugar
|
| Great points in there -- some of them are style/preference
| but I can definitely see benefits to a bunch of them.
|
| The string interpolation point you might want to update
| (Rust does that now!)
|
| Named arguments are also quite amazing.
|
| Again, fantastic list -- saved! I've been meaning to give
| Swift a proper try lately and this is a great reference.
| georgelyon wrote:
| For the record "No macros", is one of the things that is
| out-of-date. There is some discussion about it in the
| comments... maybe I'll be forced to actually update it :)
| hardwaresofton wrote:
| After having written a few of them at this point at
| $DAYJOB and on my own... They're actually not so bad at
| all -- it's quite nice the world that they open up.
|
| I'd venture to say most people are mostly annoyed at the
| _overuse_ of macros (where a simple function would do).
|
| Rust's attribute system is something it REALLY got right
| -- stuff like #[cfg(test)] and the conditional
| compilation stuff is really really impressive. Not sure
| what cross platform dev looks like in Swift but the bar
| is quite high in Rust land.
| Redoubts wrote:
| Honestly I wish I could use it more for boring back end
| business logic, too.
| pharaohgeek wrote:
| Couldn't agree more! I find it to be a very elegant language
| and a real treat to program in. I do mostly Java for work, and
| wish Swift had the open source ecosystem that Java has. There
| are so many support libraries and frameworks in the Java world
| that make it easy to develop complex applications. I wish Swift
| could say the same.
| __rito__ wrote:
| Does something similar exist for Rust?
| jocaal wrote:
| probably, I didn't really check it, but I found [1]. Rust has a
| lot of support for embedded systems, even from the companies
| that provide the chips, like Espressif.
|
| [1] https://github.com/rp-rs/rp-hal
| ComputerGuru wrote:
| Absolutely. There have been a lot of discussions here on HN
| about embedded rust in the past so you might want to search
| those on algolia to catch up but look at embedded_hal, embassy,
| or droneos as starting points.
| freddygm wrote:
| I love Swift. Hope it gets more popularity outside Apple just
| like like Zig or Rust.
| kristianpaul wrote:
| About time !
| jlundberg wrote:
| Looking forward to trying this out!
|
| Another place Swift seem to be getting traction in is godot.
|
| Miguel De Icaza's talk on the topic is highly recommended:
|
| https://m.youtube.com/watch?si=WNxwcTPGFbJABKez&v=tzt36EGKEZ...
___________________________________________________________________
(page generated 2024-03-06 23:02 UTC)