ClojureDart icon indicating copy to clipboard operation
ClojureDart copied to clipboard

Can't `with-open`

Open daveliepmann opened this issue 2 years ago • 4 comments

Describe the bug with-open will not compile.

Does your problem persist after clj -M:cljd clean && flutter clean? Yes

To Reproduce Steps to reproduce the behavior:

  1. Create any ClojureDart project. I reproduced with your first app on sha 303e2621391abaf52a7179efb848bf6d73ebb2e8 but it was also present on 6c1b1538310862dfe3fc3960fb897cf5de5a4b59 in another project
  2. Modify the source to include any with-open form. It breaks with any with-open form but the simplest I could invent was:
    1. add ["dart:io" :as io] to namespace :requires
    2. replace "Let's get coding!" message with (with-open [client (io/HttpClient)] (str client " foo"))
  3. See error:
Compiling to Dart... @10:09:59
  acme.main
Keep calm and fix bugs! 👑
Error while compiling with-open
⛔️ Unknown symbol: with-open at line: 15, column: 13, file: acme/main.cljd
Faulty subform and/or expansion with-open
While compiling (defn main [] (f/run (m/MaterialApp .title "Welcome to Flutter" .theme (m/ThemeData .primarySwatch m.Colors/pink)) .home (m/Scaffold .appBar (m/AppBar .title (m/Text "Welcome to ClojureDart"))) .body m/Center (m/Text (with-open [client (io/HttpClient)] (str client "--foo")) .style (m/TextStyle .color m.Colors/red .fontSize 32.0))))

Expected behavior with-open should compile, create its bindings, and then .close the bindings

daveliepmann avatar Dec 05 '23 09:12 daveliepmann

I ended up "writing" my own with-open, but then I soon realized that half the things I wanted to with-open were actually closed with .cancel and not .close. And then some more had to be .dispose'd...

valerauko avatar Feb 18 '24 12:02 valerauko

And creating a closable protocol would require lots of tactical extensions. I suspect that with-open must stay true to its original spirit of relying on conventions and not interfaces. Something like?

(with-open [controller (xxx) :close .dispose] ...)

cgrand avatar Feb 20 '24 00:02 cgrand

I propose adding with-open to CLJD with the following deviations from CLJ: 1/ allow for keyword options in the bindings vector (options apply to the previous binding) 2/ only supported option is :close whose value is a form into which the resource is threaded (as per ->). Default value is .close. When the close is itself async, the user would have to write :close (-> .terminate await). Is it common enough to mandate an :await-close option? I don't think. 3/ allow destructuring in bindings (useful for example with StreamController where stream and sink fields have to be used). It doesn't make sense in CLJ where there's no :flds destructuring.

However with-open doesn't cover Dart streams. We need something like Dart's await for. There are at least two distinct macros/fns: one to reduce (should we expect the reducing function to return a future? If not should we provide two reduce variants? Should we also consider transduce? Or should we go the areduce way?) and one to perform side-effects (dostream to riff on doseq).

cgrand avatar Jun 12 '24 22:06 cgrand

Related #287

cgrand avatar Jun 12 '24 22:06 cgrand