3,031 karma · joined November 7, 2011
I'm attached to a tmux session. gdb is probably running in a split with vim.
My views are not necessarily those of my employer.
I live in the Chicago burbs, but I work in the loop. I'd love to buy you a tea, coffee, or a beer to talk about start ups, Clojure, C++, Lisp, Python, toolchains, Bazel or other tech.
github: https://github.com/emidln
bsky: https://bsky.app/profile/emidln.com
email: emidln@gmail.com
(-> (from [:cities :c])
(join [:population :c] [:= :c.name :p.city-name])
(select :c.name :c.pizza-rank :p.population)
(order-by [:c.pizza-rank :asc]))
It's handy for a lot of reasons, but unless I had mostly static queries (changing just some where clause params), I would always seek out a AST library rather than attempt string building for a SQL use case.I configured my current laptop to screen off on lid close and to shutdown after 5 minutes. I'm probably just weird.
import sys
if sys.version_info[0] < 3:
print("Needs Python 3+")
sys.exit(1)
else:
prog = r'''
def help():
print("Help: ...")
def do_spam(*args):
print("spamming")
def main(args):
match args:
case [subcommand, *args]:
return globals()[f'do_{subcommand}'](*args)
case _:
return help()
if __name__ == '__main__':
try:
status = main(sys.argv[1:])
sys.exit(int(status if status is not None else 0))
except Exception as e:
import traceback
traceback.print_exc(e)
sys.exit(1)
'''
compile(prog, '', 'exec')
exec(prog)If you're doing application development, it's nice to have a language that truly cares about backwards compatibility and interoperability with a common platform. It means I can focus on solving problems and not incidental complexity. I can easily hack Clojure from the comfort of a pom.xml if necessary.
I'm not working in Clojure right now because I found interesting work outside of application development, but when I was last looking in 2018, I could get roughly all of the things I wanted from a job and still hack Clojure from a CIDER REPL in Emacs all day.
What can be parameterized depends wildly on the SQL database in question. I haven't used one that could parameterize table names (for use in dynamic JOINs or CTEs) and many cannot parameterize values outside of a WHERE clause. Dynamically selecting which function to call, clauses to add or subtract, and sort orders are just a slice of places parameters don't help.
In short, parameters alone do no eliminate the need for a query builder. A good query builder should appropriately parameterize values as the underlying database supports and hopefully uses a type system or validation to constrict the domain of values it uses to construct parts of the expression that cannot be parameterized.
I second the parent post. I've billions of messages through SQS at a previous job and I can remember having issues with SQS availability exactly once (due to a systemic failure involving DyanmoDB where cascading failures took down almost everything (and all of our integrations) that would have hosed us completely if not for our durable-queue/s3-journal[0] at the edge). SQS is simple to use, does what it says, and has very good SDK support. A++++ Would build a business on top of again!
;; don't let randos launch missiles
(binding [*read-eval* false]
(read-eval "#=(launch-missiles!)"))Clojure really encourages data-oriented programming, similar to what you often find in Python codebases. Mutation isn't the default in clojure for common data structures, so writing your iterative code is just more work than writing functional code using the immutable defaults. Language design has a big impact here. That's not to say you can't write imperative mutation heavy code in Clojure, but you're either going to fight the language or build up your own utility libraries to do it. It's there, but it's rarely idiomatic and often seen as a performance tradeoff.