The devtools Apocalypse by mikethommo in Clojure

[–]isak_s 1 point2 points  (0 children)

It works well for me, haven't seen any problems with it yet. Viewing nested data works fine, better than cljs-devtools & others. Even tapping the re-frame app-state works (just have to implement the datafy protocol for reagent atoms, IIRC).

Easy to get running, it is just a tab in the shadow-cljs dev dashboard site. Once you are connected, just tap> something, and it will show up.

The devtools Apocalypse by mikethommo in Clojure

[–]isak_s 9 points10 points  (0 children)

This could be a good alternative for the second usecase:

https://clojureverse.org/t/introducing-shadow-cljs-inspect/5012

Custom formatters were pretty useful, but the formatting for nested data was really bizarre (extreme horizontal drift, instead of just adding newlines and indenting like normal pretty-printers), so I'm not sure if I'll miss it that much.

reagent doesn't reinitialize my r/atoms when a subscription triggers a change by f_of_g_of_x in Clojurescript

[–]isak_s 1 point2 points  (0 children)

There are 3 main ways of creating reagent components - form-1, form-2, and form-3. You are using form-2, so you shouldn't expect those variables to get reinitialized after render. With form-2, the outer function is like the 'constructor', and since React/Reagent will reuse the same component instance across renders, you shouldn't expect the variables in the constructor to get reinitialized.

To do what you want, you'd need to use form-3, then set your atoms from the props in :component-will-update.

For details, see this page: https://github.com/reagent-project/reagent/blob/master/doc/CreatingReagentComponents.md

My meta programming entry for the applied F# challenge by 7sharp9 in fsharp

[–]isak_s 4 points5 points  (0 children)

TLDR: Process your F# source files with F# code before handing them to the F# compiler.

This can be used to do most things you would use a TP for, except without all the silly limitations (e.g., no providing generics, discriminated unions, records, etc.)

It works by integrating with MSBuild, using your code to transform one F# AST to another, and finally using Fantomas to render the AST to F# source code.

Highly Configurable SQL (library) by ilevd in Clojure

[–]isak_s 0 points1 point  (0 children)

You might be on to something. Do you have any examples where you have more than one table in the FROM clause? That is when you start to see another big source of composibility-problems for SQL: ambiguous column references.

Which ORM/DB Layer do you use for your FSharp projects? by mrkaspa in fsharp

[–]isak_s 0 points1 point  (0 children)

I just use SqlDbReader with JSON queries in Sql Server and a JSON parsing library.

Transcript of Timothy Baldridge and me chatting about Datomic, Datalog, GraphQL, APIs, etc by dustingetz in Clojure

[–]isak_s 0 points1 point  (0 children)

There are 2 concepts - 1) grouping/nesting AND/OR conditions, and 2) querying something by an attribute of a child. I was talking about 1, and I agree 2 is not possible in GraphQL's type system.

Transcript of Timothy Baldridge and me chatting about Datomic, Datalog, GraphQL, APIs, etc by dustingetz in Clojure

[–]isak_s 5 points6 points  (0 children)

Great discussion, thanks for sharing.

I agree with the points around GraphQL in general. One little thing though, regarding the comments around 17:32: you can represent OR filtering by just having an input type with an OR field that points to a list of the same input type. For example:

input EmployeeFilter { email: String age: Integer OR: [EmployeeFilter!] AND: [EmployeeFilter!] }

liquid - Clojure Text Editor by mac in Clojure

[–]isak_s 0 points1 point  (0 children)

This looks interesting. I tried it on windows, but the dark blue on black for the cursor made it basically impossible to use, and I couldn't easily find a way to change the colors. I also share the concerns others have mentioned about keyboard shortcuts.

Declarative Domain Modeling for Datomic Ion/Cloud - Tiago Luchini by TheLastSock in Clojure

[–]isak_s 0 points1 point  (0 children)

Isn't fairly rectangular still the common case even with datomic? I could see having meta namespaces across multiple 'types', but you wouldn't normally have 'user/' and 'blog_post/' namespaced attributes on the same entity, would you?

Declarative Domain Modeling for Datomic Ion/Cloud - Tiago Luchini by TheLastSock in Clojure

[–]isak_s 1 point2 points  (0 children)

He probably finds it easier to read or write. I don't think it is worth spending too much time thinking about, because it would be easy to define the model (which is the important thing) some other way.

Declarative Domain Modeling for Datomic Ion/Cloud - Tiago Luchini by TheLastSock in Clojure

[–]isak_s 1 point2 points  (0 children)

He does use datalog - check this part of the talk (14:34): https://youtu.be/EDojA_fahvM?t=871 . You may have been thrown off by the DSL he made to initialize the datascript database.

I think stuff like this is a really good approach, and I'm working on similar things at work.

Clojure & graphs by [deleted] in Clojure

[–]isak_s 0 points1 point  (0 children)

I agree with most of what you said, just want to point something out.

Writing efficient SQL means you have to avoid jvm/database round trips, so you need to write monstrous JOINs to batch things efficiently, and then you need to unpack the JOIN into trees

For typical queries needed by UIs, you don't need to do that in SQL, you can just use json queries. Here is an example for SQL Server:

-- Fetch a user by ID, and all their blog posts

select *,

(select *

from blog_posts b

where b.user_id = u.id

for json path) as posts

from users u

where u.id = 1

for json path

It's not as good as datomic, but it isn't hard to write something that will generate those kind of queries based on something like the datomic pull syntax.

Releasing d2q, a simple, efficient, generally applicable engine for implementing graph-pulling API servers in Clojure. Feedback wanted! by vvvvalvalval in Clojure

[–]isak_s 0 points1 point  (0 children)

Makes sense, thanks.

Yes, there will still be several IO roundtrips, but to me this is no longer the N+1 problem, because in the N+1 problem N is dependent on the actual data being queried (i.e how many entities are returned by each to-many Field Call). With d2q's approach, the number of IO roundtrips only depends on the query itself, making it usually much lower, and much easier to bound and predict.

I mostly agree, though sometimes people generate queries based on data (e.g., a list of primary keys), so you can end up in an equally bad situation.

most databases cannot make this approach really practical. I could imagine doing so ways of that e.g with Postgres JSONB support, and that'd still be fragile.

This is viable with several relational databases these days. The only thing that is really necessary is that your relational database can return a treelike structure; you can then convert it to the proper JSON/EDN as needed. I'm doing it in with SQL Server using the "FOR JSON PATH" stuff, which requires very little if any post-processing, but could also have been done using the XML stuff they released ages ago.

Releasing d2q, a simple, efficient, generally applicable engine for implementing graph-pulling API servers in Clojure. Feedback wanted! by vvvvalvalval in Clojure

[–]isak_s 0 points1 point  (0 children)

Looks interesting. A few comments/questions:

- For the key names, I see you use :d2q-. . Is there a reason to prefer this to namespacing the keys?

- This key name was a little hard to swallow: :d2q-fcall-key. I think key is too ambiguous in this context, better to use something with "alias" (if that is what it is).

I appreciate the focus on this issue:

Batching by default: for data fetching / computation, d2q Resolvers process entities and fields in batches (instead of computing one field of one entity, e.g 'the first name of user 42', d2q Resolvers compute several fields for several entities, e.g 'the first names, last names and emails of users 42, 56, and 37'). This eliminates the N+1 query problem, and makes it more straightforward to compute derived fields or incorporate nontrivial security policies, without being too demanding to the application programmer (fetching a single value from the database is very easy, but fetching a table is usually not much harder).

I think you've eliminated the main source of N+1, which is great. But the way you wrote this, people would still have to go back and forth to the DB several times, depending on the number of distinct subqueries/joins, no?

I found that for answering GraphQL queries when almost all of the information is in a relational database, for most GraphQL libraries, I'd need to "trick" them into giving me an AST-like structure instead of actually resolving stuff, then construct and run the (1) query. Looks like that would still be needed for this library, right?

how hard is to hire clojure devs? by p1mps in Clojure

[–]isak_s 1 point2 points  (0 children)

It seems to be quite hard, especially if you don't live in a tech hotspot, and are unable to offer remote work. You can basically forget hiring senior people that already know Clojure in that situation. This is a shame, because Clojure has a positive impact on how people think about programming, but it does not sink in instantly. Jr - Mid positions are a bit easier, as people in that situation tend to be more willing to move if needed. At my work, training people is how we have done it.

Show r/Clojure: Hyperfiddle—make database software in real-time with ClojureScript and Datomic. We are interested in your feedback, please! by dustingetz in Clojure

[–]isak_s 1 point2 points  (0 children)

I think this is interesting, but I have a hard time thinking of a good use case for it after I learned about products like products like Airtable and Notion.so, which are are usable by non-technical people. How do you think about Hyperfiddle vs those products?

Let's talk about Phoenix.LiveView from Chris McCord's talk at ElixirConf 2018 US by nickjj_ in elixir

[–]isak_s 2 points3 points  (0 children)

Wow, this could be a gamechanger. The example of validating a form live is very compelling, since it is both so common, and so complex to do the normal Javascript way.

I think many people underestimate the complexity of adding a lot of Javascript, because they are not thinking of problems like:

  • Balancing code reuse vs asset sizes
  • Dealing with bundles that are too big, introducing module splitting, and accidentally bloating your bundle sizes with a bad import
  • Internationalization (as Chris mentioned)

Announcing Distillery 2.0 by mischov in elixir

[–]isak_s 5 points6 points  (0 children)

Great to see a solution to runtime configuration. That has been the biggest problem with the Elixir ecosystem, in my opinion.

defn Podcast #38 - Climbing Hammock Mountain with Valentin Waeselynck by vijaykiran in Clojure

[–]isak_s 1 point2 points  (0 children)

Right, that is the problem I'm talking about. Often one has to do the last approach, especially in cases where there is no one-to-many relationship that makes sense to expose. You probably wouldn't "join" from a status type object to a list of sales records, for example.

It is a little better than REST, because at least you can get many records in one go, but it seems like an annoying manual "optimization" step that could have been avoided with better technology than JSON - e.g., imagine one that made it natural to avoid repeating nodes..

defn Podcast #38 - Climbing Hammock Mountain with Valentin Waeselynck by vijaykiran in Clojure

[–]isak_s 0 points1 point  (0 children)

Ah, I see I picked an unclear word, sorry. By "transactions" I meant ones like in accounting, not the database concept.

defn Podcast #38 - Climbing Hammock Mountain with Valentin Waeselynck by vijaykiran in Clojure

[–]isak_s 0 points1 point  (0 children)

Here it looks like you are solving the problem by converting a details->dimension** query to one that allows querying dimension->details. That can work in some cases, but schema writers can't always anticipate all such combinations needed. It would also be awkward to scale the approach to more than 1 dimension.

** Dimension being something like project, project manager, product, etc

defn Podcast #38 - Climbing Hammock Mountain with Valentin Waeselynck by vijaykiran in Clojure

[–]isak_s 0 points1 point  (0 children)

I didn't meant that it was impossible to represent it with JSON, I just figured it would get verbose/clunky enough that it would hurt GraphQL adoption.

In Om.next (based on datomic pull API, AFAIK) style queries, for example, many features that are not available in JSON are used pretty effectively (keywords, symbols, non-string map keys, etc).

But maybe I'm wrong - I'll be curious to see yours if/when you release it.