11 ms·
Embedded Swift on the Raspberry Pi Pico
- kristianpaul 3y agoAbout time !
- RetpolineDrama 3y agoSuper 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 3y agoDart 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 3y ago> 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 3y agoThere are now 2x as many syntaxes for the same operation, if let and if != null
- RetpolineDrama 3y agoIt'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 3y agoRight. In Dart they are the same. In Swift they are distinct.
- mckn1ght 3y agoThey 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 3y ago> 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.
- 3y ago
- RetpolineDrama 3y ago>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 3y agoCorrect, Dart has enum exhaustiveness checks, associated types, and expressions as of 11-13 months ago: https://cfdevelop.medium.com/dart-switch-expressions-33145c393052 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 3y agoIn 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 https://news.ycombinator.com/item?id=39613415
- timsneath 3y agoI believe Dart has pattern matching, but not associated values of different types.
- mraleph 3y agoIn 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 https://github.com/dart-lang/language/issues/3021
- jwells89 3y ago> 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 3y agos/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 3y ago> 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 3y agoI 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 3y agogentle reminder that `if let x = x` can now be spelled simply `if let x` in current versions of Swift
- jwells89 3y agoHave been loving this feature. It’s a small but impactful QoL improvement.
- fingerlocks 3y ago> 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.
- deleted 3y ago[deleted]
- deleted 3y ago[deleted]
- jwells89 3y agoI 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.
- deleted 3y ago[deleted]
- MrBuddyCasino 3y agoSince 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 3y agoYup it's called a sum type, or a tagged union https://en.wikipedia.org/wiki/Tagged_union https://en.wikipedia.org/wiki/Tagged_union
- bmitc 3y agoThe enum example is not really a union though or is a constrained version. For example, the cases are non-recursive.
- tialaramex 3y agoUm, what? You believe unions are recursive data structures?
- bmitc 3y agoYes. For example, from Standard ML: datatype 'a list = nil | :: of 'a * 'a list
- tialaramex 3y agoI have never seen this called a "union", and that's certainly not what people mean when they speak of a "tagged union".
- bmitc 3y agoWhat 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-reference/discriminated-unions https://learn.microsoft.com/en-us/dotnet/fsharp/language-ref... https://ocaml.org/docs/basic-data-types#variants https://ocaml.org/docs/basic-data-types#variants
- tialaramex 3y agoHuh. I was thinking about this in much lower level terms, it seems weird to me to define these structures recursively when how they're actually stored is thus omitted yet that's actually crucial, but I guess if you work in a sufficiently high level system you don't care about the implementation details.
- hyperthesis 3y agohttps://wikipedia.org/wiki/Pattern_matching https://wikipedia.org/wiki/Pattern_matching since 1957 I feel ML is the most famous for it.
- bmitc 3y agoAs 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 3y agoLanguages without this feature are basically refusing to wash their hands between the morgue and the maternity ward at this point.
- tialaramex 3y ago[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 3y agoThanks 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 3y agoI 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-programming-language/patterns/ https://docs.swift.org/swift-book/documentation/the-swift-pr...)
- jsheard 3y agoHow 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 3y agoI’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.
- deleted 3y ago[deleted]
- zer0zzz 3y agoThe arc browser has a beta for windows. It’s pretty decent so far and is written in swift
- mpweiher 3y agoIt's based on Chromium, wich is C++. In terms of total code, I'd wager it's around 99% C++.
- machinekob 3y agoI think he means GUI not engine as they are indeed just using chromium engine as browser.
- zer0zzz 3y agoYes. 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.
- RantyDave 3y agoFWIW 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 https://docs.micropython.org/en/latest/zephyr/general.html
- zoecarver 3y agoBecause 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/IntegratingWithSDKs.md https://github.com/apple/swift/blob/main/docs/EmbeddedSwift/...) should mostly apply to the Zephyr SDK as well.
- RantyDave 3y agoOh look at that, right in the repo. The Apple one. Wow.
- FlyingSnake 3y agoSwift 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 3y agoWasn't the performance and tooling poor in Linux and Windows? Has something changed there?
- saagarjha 3y agoThings are changing slowly.
- machinekob 3y agoLinux is very much ok at least x64 vscode is working faster than Mac version but ofc. It is not Xcode
- sgt 3y agoHaving 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 3y agoIf you can like it despite using Xcode, then it means the language is really good.
- WanderPanda 3y agoYeah 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
- __rito__ 3y agoDoes something similar exist for Rust?
- jocaal 3y agoprobably, 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 https://github.com/rp-rs/rp-hal
- ComputerGuru 3y agoAbsolutely. 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 3y agoI love Swift. Hope it gets more popularity outside Apple just like like Zig or Rust.
- deleted 3y ago[deleted]
- jlundberg 3y agoLooking 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=tzt36EGKEZo&feature=youtu.be https://m.youtube.com/watch?si=WNxwcTPGFbJABKez&v=tzt36EGKEZ...
- pjmlp 3y agoHe also appears to be done with .NET, now that his NDA expired check on twitter/mastadom his remarks on MAUI.