Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't with-open #296

Open
daveliepmann opened this issue Dec 5, 2023 · 4 comments
Open

Can't with-open #296

daveliepmann opened this issue Dec 5, 2023 · 4 comments

Comments

@daveliepmann
Copy link

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 303e262 but it was also present on 6c1b153 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

@valerauko
Copy link
Contributor

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...

@cgrand
Copy link
Contributor

cgrand commented Feb 20, 2024

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
Copy link
Contributor

cgrand commented Jun 12, 2024

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
Copy link
Contributor

cgrand commented Jun 12, 2024

Related #287

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants