Live data from Hacker News

On the proliferation of try, and soon, await (2020)

forums.swift.org

21–30 of 44 posts

Re: On the proliferation of try, and soon, await (2020)

#21

One of the interesting things (IMO) about programming language design is how the designer can choose to make some concepts harder or easier to express, and how those decisions shape the kind of programs that are easy to write with the language. Here, Swift (it seems) makes an implicit suggestion that a developer keep their error handling tight and bounded. If you don't, the language softly penalizes you with the need…

What do you think of Java's declared exceptions (or whatever they're called)? They always seemed like a good idea to me, but were ruined by people being lazy or not understanding how to properly design exceptions.

some disadvantages:

i) There's RuntimeException which is an unchecked exception which could happen anywhere, so even the absence of a throws is not a guarantee of not throwing.

ii) In order to avoid many different throws specifiers, you end up with wrapping exceptions to a smaller set of exceptions (e.g. JNDI may throw a NamingException that wraps an IOException)

iii) IDEs offer to put try-catch { // todo } to avoid compiler errors. Developers often stop thinking then, where the right thing is more often to let it throw - e.g. I've seen FileNotFound being caught and logged (at debug) and not exposed to a caller, so a UI doesn't see it, with bad results.

Re: On the proliferation of try, and soon, await (2020)

#22
It's important to distinguish:

  asset1 = await httpGET(...)
  asset2 = await httpGET(...)
from:

  assets = await Promise.join(httpGET(...), httpGET(...))
  asset1 = assets[0]
  asset2 = assets[1]
Where the first does one request and doesn't start the next until the previous had completed, and the second does them concurrently.

BUT - you could have a language where async functions are awaited by default, and you'd have to write something like:

  assets = Promise.join([pending httpGET(...), pending httpGET(...)])
Where pending means don't await, and absence of it when invoking an async function does require it.

Presence of an 'async' decorator on functions isn't strictly needed, but does convey extra information in the API, which is useful.

Re: On the proliferation of try, and soon, await (2020)

#23
post #5

Earlier quoted context omitted.

But you broke encapsulation because locations and metadatas have an invariant that must be externally enforced. I don't think that meets the standard of well-encapsulated. If locations and metadatas must be updated together then you should only be able to do it via some method update() that takes location and metadata.

You’re maybe right, but does that mean the language should be hostile to those that don’t write well designed code?

I think a lot of programmers would say "yes" to this, enthusiastically.

Re: On the proliferation of try, and soon, await (2020)

#24
post #22

It's important to distinguish: asset1 = await httpGET(...) asset2 = await httpGET(...) from: assets = await Promise.join(httpGET(...), httpGET(...)) asset1 = assets[0] asset2 = assets[1] Where the first does one request and doesn't start the next until the previous had completed, and the second does them concurrently. BUT - you could have a language where async functions are awaited by default, and you'd have to writ…

> Presence of an 'async' decorator on functions isn't strictly needed, but does convey extra information in the API, which is useful.

I disagree. It's akin to having a `gc` decorator on a function that uses GC. Maybe useful for C++, but not useful for high-level languages like Java, Swift, Go, JavaScript, Python.

Long-term, I firmly believe `async` will reveal itself to be a mistake. It's simply unwillingness by language designers (or more likely implementors) to treat threading like GC - "that magic is OK, but this magic needs to have extra syntax".

Go chose a different route and treats all runtime magic as implicit behaviour (well, almost all - goroutines can block in loops - but they're trying to fix that, or maybe they have already). Java (project Loom) is going down the same path. It's only a matter of time Swift, Python etc. realize their mistake.

Re: On the proliferation of try, and soon, await (2020)

#25
post #21

Earlier quoted context omitted.

What do you think of Java's declared exceptions (or whatever they're called)? They always seemed like a good idea to me, but were ruined by people being lazy or not understanding how to properly design exceptions.

some disadvantages: i) There's RuntimeException which is an unchecked exception which could happen anywhere, so even the absence of a throws is not a guarantee of not throwing. ii) In order to avoid many different throws specifiers, you end up with wrapping exceptions to a smaller set of exceptions (e.g. JNDI may throw a NamingException that wraps an IOException) iii) IDEs offer to put try-catch { // todo } to avoid…

> iii) IDEs offer to put try-catch { // todo } to avoid compiler errors.

This is the thing that always pissed me off. The default catch block should be to wrap it in a RuntimeException and rethrow it.

Re: On the proliferation of try, and soon, await (2020)

#26
Linking to forum discussions is a bad substitute for a blog post presenting a view, and I can't determine why OP is linking this discussion from last year today. I wasn't able to take away any value from this link because I couldn't read all 153 comments in it.

Re: On the proliferation of try, and soon, await (2020)

#27
post #15

Are there any popular UI frameworks/architectures that are actually compatible with implicit context switching? I see a lot of desire to purge await from languages but I find the explicit control necessary. What would UI code look like with implicit yields?

Kotlin is used to write UI code, and potentially-yielding methods are called with ordinary function call syntax. Kotlin does not have the "await" keyword, but it does have an analogue to the "async" keyword, called "suspend".

Here is a post from Kotlin's language designer on their philosophy: https://elizarov.medium.com/how-do-you-color-your-functions-...

Re: On the proliferation of try, and soon, await (2020)

#28

Earlier quoted context omitted.

You’re maybe right, but does that mean the language should be hostile to those that don’t write well designed code?

I think a lot of programmers would say "yes" to this, enthusiastically.

Yes. In particular you would want badly designed code to stand out.

Re: On the proliferation of try, and soon, await (2020)

#29
post #19

Earlier quoted context omitted.

Consider this to be the only function that modifies locations and metadatas. It is the function that is supposed to maintain that invariant. You can pass in location and metadata (or make this a method on an object with those values as private members) without changing my point. Under the rules laid down by the original poster in the link, functions which only modify well-encapsulated types via their public APIs cann…

> well-encapsulated types via their public APIs cannot violate invariants … of those well-encapsulated types. Throwing an exception like this cannot break an internal invariant of the list object which is what the author is saying. You can’t break the list object which sounds crazy by modern standards but in languages without this kind of encapsulation (like C) this can and does happen.

That's a very useful guarantee, I agree, but it's not a good enough reason to not have "try" as a syntax.

Re: On the proliferation of try, and soon, await (2020)

#30
post #24
post #22

It's important to distinguish: asset1 = await httpGET(...) asset2 = await httpGET(...) from: assets = await Promise.join(httpGET(...), httpGET(...)) asset1 = assets[0] asset2 = assets[1] Where the first does one request and doesn't start the next until the previous had completed, and the second does them concurrently. BUT - you could have a language where async functions are awaited by default, and you'd have to writ…

> Presence of an 'async' decorator on functions isn't strictly needed, but does convey extra information in the API, which is useful. I disagree. It's akin to having a `gc` decorator on a function that uses GC. Maybe useful for C++, but not useful for high-level languages like Java, Swift, Go, JavaScript, Python. Long-term, I firmly believe `async` will reveal itself to be a mistake. It's simply unwillingness by lang…

I believe if you read far enough in the thread you’ll see Swift’s “Structured Concurrency” proposal does the same thing. In Go you must `go ...` to invoke concurrency. In Swift that would be `async let = ...` under the proposal (which has already been implemented) on main. `async` just says this function returns a “future” and `await` just desugars the future. I prefer Rust’s approach where the future is an actual type, but there’s a nice element to swift’s where it is prt of the syntax, as is similar with swift’s optionals.
Post reply on HN