I noticed that in many examples datomic attributes are named using camel case (for example startMonth instead of start-month in mbrainz schema:
https://github.com/Datomic/mbrainz-sample/blob/master/schema.edn#L78) which would definitely be more Clojure idiomatic. Why is this so?
Only explanation that comes to mind is that camel case looks more familiar if used from e.g. Java. Is this the reason? Are there any downsides to using kebab-case in Datomic if the db is used from Clojure?
As in Clojure itself, the naming convention (camelCase, snake_case, or kebab-case) is up to the user.
A large part of the target market for Datomic is Java users, and many of the docs therefore use Java convention. Other parts of the docs and libraries like Tupelo Datomic use Clojure convention.
Related
I was watching a Google Next session, as I'm interested in Google's cloud and their Go language.
Developer ecosystems/communities have their ways of doing things, cultural customs, which can be really alien to outsiders who don't have the experience to fill-in the gaps.
So I have a few noob questions:
What language is this?
What language does Google use in samples, Python, Go, or pseudo code?
Why is there a call to getFailedInserts() but the result of the get isn't assigned to anything?
Is it normal to use what I call magic strings, i.e. "WriteMutatedRecords", as instructions instead of naming a method as such or using an enum, or string consts?
The code example is Java using Apache Beam programming model (https://beam.apache.org/)
I believe the complete code from the slide is here:
https://github.com/ryanmcdowell/dataflow-dynamic-schema/blob/master/src/main/java/com/google/cloud/pso/pipeline/DynamicSchemaPipeline.java
The code from slide:
tries to insert data into a table 'events_table'
If it returns a transient error from Big Query API (for example "column 'foo' does not exist") it runs a table mutation adding 'foo' and inserts data again.
It is a pattern to create flexible tables into Big Query which is a predefined schema columnar database.
The code example looks like it is written in Scala or Java. You can tell from a number of indicators:
The code has a Java-style syntax
Methods are called on objects (e.g. input), which means it is an object-oriented language
new BigQuerySchemaMutator() is typical for a Java - style constructor
These indicators do not, however, give any indication wether it is Scala or Java. The syntax of these languages is very similar, and both are JVM - lanugages.
The strongest indicator for Scala in my opinion is that the code is written in a functional matter, and it contains two method invocations on BigQueryIO, which could either be a static method for the class BigQueryIO itself in case of Java, or is a method defined on the object BigQueryIO in Scala, which is a common design pattern in the language.
There is, however, the final ; which would only be necessary with Java.
For someone reading the code example this question is actually not important, because Apache Beam (which is the SDK that seems to be used here) is a Java library - which can be used both in Java and Scala.
The result of getFailedInserts seems to be further processed by calling .apply on it. This kind of style is called functional programming.
It's a whole different approach to programming, instead of the common procedural programming patterns found in most other lanugages. (e.g. storing something in a variable / variables in general)
Note that this example doesn't actually contain any functional programming per se (e.g. higher order functions alias lambdas), but the functional programming style is obvious.
It is always considered best practice to not have magic strings, but for such a code example they probably wanted to keep the code as simple as possible - as it is a one-liner already (allthough with line breaks).
In my Clojure project, I am using Clojure Spec but If I need to use some lib like compojure-api then I need to use Schema.
What is the advantage one over the others?
Why would I consider one over the others?
Which one is good for compile type checked?
These are three merely different approaches to give the developer some type safety. All the three offer their own DSL to describe the schema/type of data but they are very different in philosophy. They are all actively maintained and have a nice community.
This is an opinionated overview based of my experiences.
core typed
core typed tries to extend the clojure language with additional macros to annotate functions and vars with static type information. It then uses static type analysis to ensure that the code matches the type info (that is it produces and consumes data of the right types).
Some advantages:
Static typing in general is a very strong tool. If you are familiar with staticly typed programming languages you will appreciate this very much.
Many bugs can be found during compilation time. No more NullPointerExceptions!
Some drawbacks:
Changing something in type or code may require extra work to propagate the changes through all parts of your code. And sometimes it is just too complicated to write type info or correct programs.
Static code checking will slow down your compile times and may slow down your development workflow.
Schema
In Schema you also write type annotations but type checking happens runtime. It encourages you to construct schema declarations dynamically and lets you specify where you want to check for schema and where you do not want its funcionality.
Some advantages:
Very friendly DSL to describe data schema.
Various tools. For example: Data generation for generative testing, tools to explain why a schema does not match.
Some disadvantages:
Only checks for schema where and when you tell it to do so.
External library, not supported by the core team.
Spec
Spec is the latest player with a philosophy borrowed from Racket lang. It is (going to be) part of the Clojure core library from the Clojure version 1.9.
The basic idea is to have entity types specified by the (namespaced) keys in a map object. Spec declarations are stored in the application's registry bound to namespaced keywords. Spec is very strong in sequence validation.
Some advantages:
Part of the Clojure core, not an external library. It is now used for parsing macro arguments and also for documentation purposes.
The community is very excited about it resulting in interesting ideas such as using spec in genetic programming and generative testing.
Some disadvantages:
Will be available in Clojure 1.9 which is not yet a released stable version. It is still a new technology not widely used.
Spec do not look like the data they are describing.
Personally, core.typed feels intimidating and core.spec feels immature so I use schema in production. My advice is the following:
If you need static type checking then core.typed is the way to go.
If you want to do parsing then core.spec is a nice choice.
If you want simple type descriptions then schema will be a good fit.
In general, is it possible to use Scala Frameworks with Clojure and vice versa?
I heard a lot of good things about Akka and Play but i like Clojure better than Scala.
It surely is possible. You can call clojure code from Java and vice versa. You can do the same with scala as well and though I have never tried it, I think you also can call Scala from clojure and vice versa.
But I cannot imagine how one would do that in a useful way? Clojure being data first vs. classes for Java and Scala being the main concept I don't see how one would use them on the same parity.
Maybe writing a wrapper around the library from one side or the other so you can stay within one language for your business logic, that would seem useful.
OTOH, that I dont see it being useful, doesn't mean there is no use case for it.
Still, I would suggest doing a prototype with Scala and Akka for your problem and compare it to a prototype with clojure and maybe core.async and see what fits you better.
There are interoperability issues between Java and Scala code. Essentially, you can use Java libraries from Scala without any problem, but using a Scala library from Java will have some limitations. Some features such as traits and implicits aren't part of the Java language, and they can be essential parts of libraries. I suspect that you'll run into the same issues you have with calling Scala code from Java if you end up picking Clojure.
All in all, if you're going to use the Play! Framework with Clojure, I'd recommend using the Java API instead of the Scala one. There is also a Java API for Akka.
I am just beginning to learn how to write software that accesses an SQL server. It seems that each server implementation (Postgres, MySQL, etc.) offers API libraries for various languages (my code is in C and C++, though solutions for Java and Python would also interest me). I'm a little wary of depending on these libraries, however, because I'd prefer a vendor-neutral solution.
As near as I can tell, Microsoft's ODBC API was meant to solve such problems for C/C++ (and JDBC for Java); unixODBC seems to be one popular implementation. Am I right even so far?
Moreover, do any such libraries provide an object-oriented interface? It would be nice to not simply embed SQL queries into another, more featureful language; I'd like to have a wrapper that mimics the style of the rest of the language, too.
So is there a preferred solution along those lines? Am I asking for something weird?
As near as I can tell, Microsoft's ODBC API was meant to solve such problems for C/C++ (and JDBC for Java); unixODBC seems to be one popular implementation. Am I right even so far?
Yes. The equivalent of ODBC or JDBC for Python is called the DB-API. Perl's equivalent is called DBI.
Moreover, do any such libraries provide an object-oriented interface? It would be nice to not simply embed SQL queries into another, more featureful language; I'd like to have a wrapper that mimics the style of the rest of the language, too.
Yeah, there are a bunch of things like this for different languages. C# has LINQ, Smalltalk has Roe and GLORP, Python has SQLAlchemy and SQLObject (and Django in Python has quite a bit of query power built into its ORM (see Simon Willison's notes)), Ruby has ActiveRecord, and so on. I don't know what you'd use in C++ but I bet it has to use a lot of ugly template hacking to approach these.
All these choices might seem overwhelming, but chances are your choice of language will be shaped by something other than the convenience of working with relational data. (If not, you should consider Prolog.) That will probably tie you more or less to some ORM you hate just like the rest of us.
Indeed, ODBC/JDBC are libraries that help make the calling interface standard between vendors, but you're right that each respective RDBMS has its own flavor of SQL. ODBC/JDBC doesn't help abstract the SQL syntax.
One solution to move literal SQL out of your application code is to implement queries in stored procedures that reside in each database back-end, and then use ODBC/JDBC to call the stored procedures. You can define stored procedures with similar names and calling interface for each flavor of RDBMS you use. But be aware that the stored procedure language is also variable from one vendor to the next.
Another solution is to use an "object-relational mapping" technology such as Hibernate for Java, or NHibernate for .NET. These technologies can make it feel more "object-oriented" to work with databases, and free you from writing literal SQL in many cases.
But most ORM tools tends to focus on very simple queries. If your query is at all complex (using a GROUP BY or a JOIN for instance), using the ORM tool is harder than using literal SQL.
See also "Good ORM for C++ solutions?"
If SQL troubles you that much, you're probably not going to be happy using an RDBMS at all. Some programmers don't see the value to the Rules of Normalization, for instance. If that's true for you, you might want to look into the emerging technologies for non-relational data stores, including:
BerkeleyDB
Project Voldemort
CouchDB
ODBC/JDBC attempt to abstract away the database interface to provide a consistent programming model. Bear in mind that, by using such a least-common-denominator interface, you cannot take advantage of specific, non-standard features that a given DB may offer.
To get an object oriented interface to your data model, look into Object Relational Mapping (ORM) solutions such as Hibernate. ORM solutions map your objects to their representation in a relational database, generally making data persistence much simpler from an application programming perspective.
Quince is a C++ library that lets you use C++ syntax and C++ types with the feature set of SQL. Currently it supports PostgreSQL and sqlite only, but new backends can always be added. See quince-lib.com. (Full disclosure: I wrote it.)
Take a look at Qt. It is not a library, but a complete framework. It has a very excellent SQL module.
Qt SQL is an essential module which provides support for SQL
databases. Qt SQL's APIs are divided into different layers:
Driver layer
SQL API layer
User interface layer
http://doc.qt.io/qt-5/qtsql-index.html
Those of us who use multiple languages to solve problems can combine them in a lot of ways. Personally I use PL/SQL, XSLT, JavaScript, and Java plus the pseudo languages HTML, XML, CSS, Ant, and Bash. What do you use?
Paraphrasing one of my favorite quotes:
Always write your code as if it were going to be maintained by a homicidal maniac that knows your home address.
I have a D/MySQL/JavaScript[1]/HTML/CPP[2] app.
[1] compile time D template generated
[2] C pre-processor used to generate apache configs and SQL sprocs
Yes, I am trying to take things to the insane! ;)
I work on a desktop application, so my alphabet soup looks like: C# and C++ as well as XML and T-SQL.
Java + Clojure works very well as a combination for me.
Java is good for the low level code that needs to be well optimized. It also gives you access to the huge array of libraries in the Java ecosystem.
Clojure is great for rapid development of higher level code, working interactively in a REPL. It has great support for meta-programming and concurrency, and I often use Clojure to "glue together" Java based components into a working application.
It helps enormously that Java and Clojure run in the same JVM - calling between the two is very easy and has effectively zero performance overhead.