Hi,
Alan is a new approach to "low code" for the rapid development of data centric applications. I'm one of the developers of the platform.
> Instead of the traditional relational database + 3GL or 4GL language, the core of Alan is a data modelling language that automatically generates full stack applications.
Well you’ve launched, so you should be meeting the needs of potential customers.
In your shoes I’d turn around and make a 1 minute video and upload it to YouTube within 20 minutes, showing what your system is and what these data structures look like.
If you have an Apple Mac, the screen recording is built right into QuickTime, just plug your telephone headset into the machine to record some narrative as you go.
Seriously, why launch without showing people what it is? 10 years coding, not willing to spend 5 minutes to record it and show us?
I’m not interested in reading about the deployment process. Really not.
I disagree with your strategic view for what one should do after launch.
I think the focus should be meeting the needs of actual customers. And an intro video for people who are still deciding if they will give a chance is not one of those needs by definition.
Right after launch, you want to iterate the product for your actual users. After-launch is not growth phase, is product/market fit phase. Some friction that filters out customers that are not of the early adopter profile might even be desirable.
The only exception is if you do not have enough customers to get feedback from, then you work on this sort of thing.
An important, if subtle, point is that I am not against sales in this early stage, I am all for it. I am against investment in inbound growth-only tactics. Founders doing early sales can both overcome any deficiency in a landing page, learn about what is the best message, and improve their product along the way.
I think a good example to follow for your project is the original Rails announcement video by DHH:
https://www.youtube.com/watch?v=Gzj723LkRJY
Maybe you can do a similar app in way less time!
Even if a screenshot (or screen capture, or some code) is pretty useless, it helps give the right context, and tells me this is actually a thing, and not just a hope.
I'm disconcerted after reading this thread, seeing that some people somehow think that "low code" means "low-level code" (really?) and mistaking a collared shirt for legs. I'm going to assume it's because this post was made early in the morning and no one has had their coffee yet.
However, the logo to me did look like a blood bag with some yellow liquid in it and two tubes sticking out at the bottom. (When shown on white background, you cannot see hair on the guy's head - https://alan-platform.com/pages/tuts/introducing.html ) Anyway, the program looks very intuitive in its purpose and goal!
I guess you could compare it to the model driven Power Apps. However, Alan's modeling language is more powerful. Especially the concept of state groups that allows you to specify complex business rules in the application model itself.
It's the process of laying down the rules for the data in your application that drives development in Alan. Unlike Google App Builder, you don't start from a drag and drop UI builder. Although a drag-and-drop UI builder is something we might want to add at some point. For most applications though, the generated UI is plenty powerful, because what it needs to support is perfectly specified in the datamodel.
I am not sure I get it right, but is this supposed to be a modern MS Access?
If it is, I think it is a very welcoming innovation. I believe there are a lot of use cases in business that are currently under-engineered into Excel or over-engineered into complete web apps, SAP or salesforce applications.
BTW, it is a mystery to me why MS Access itself, that is still around, lost this post.
You could look at it like that. But because data modeling language underneath is so much more detailed and powerful, the default UI is also much more useful than what you get in Access or any other relational database. The basic target audience is similar, but Alan scales a lot better to more complicated applications.
As you say, we see Excel being stretched to doing things it cannot do, and on the other hand custom apps being built for things that don't need to be so specific. There is a place for low code the way Outsystems does it for instance, but we believe a lot of businesses would be better served by something like we're offering here.
Some feedback:
* "low code" is confusing
When I started reading I thought low code, meant low "level" code, something like assembly or rust. After reading a lot in the page I saw it meant not writing imperative code. I think the term Model Driven Engineering would be more appropriate: https://en.wikipedia.org/wiki/Model-driven_engineering
* How do I model business rules?
How do I model a State machine?
I want to specify that once an order has been created I want to send it to the procurement department.
* How do I connect with external APIs systems?
* You mention that you have an ERP system based on this platform.
Can we look at that code?
Can we have some testimonials?
Kudos:
* It's good that you are doing a declarative approach to business software... this is still most of the software we use and I don't think it's a solved problem.
* On using a Graph database I think this is better to model complex domains. However which graph database are you using? Neo4j, Dgraph, OrientDB or is an inhouse graph database?
> "low code" is confusing When I started reading I thought low code, meant low "level" code, something like assembly or rust.
I expected that as well from the title but at the very start they link the meaning of the term so that those of us that don’t know what it means can quickly find out on Wikipedia.
I think it’s best to do like they are doing and link the Wikipedia article.
Why not just explain it in plain English right on the page? Expecting potential users to read a wiki article just to understand what your product is seems like unnecessary friction.
Low-code is a pretty standard industry term, though. Maybe not for the HN crowd but Gsuite has a low-code tool now and the likes of OutSystems have been doing it for years.
Alan is definitely related to model driven engineering. It's a different take on what a model can specify, and models drive everything we do.
https://www.m-industries.com has some testimonials. We can't share those particular data models, but if you're really interested get on the forum and we can dig into some of those areas.
External systems can be interfaced with using our bridge application that can work with relational databases. We have tooling to rapidly build custom connectors using our interface specification language. One area that Alan shows it's still early days is that we don't have a shelf full of ready made connectors.
Our stack is all home grown. We run on a tiny custom built Linux distro. The graph database is also in house. There wasn't anything out there that fit our needs (like being 100% push/subscription based). Luckily Alan also helps keep our line count pretty low throughout the stack.
That's probably the intention. You either get the term and find it self-evident (win), or you ask what that means or click so you can find out what low code means. Either way they win.
Let's say I want to develop a multi user todo and I've followed the examples and now have some Users who log in entering a password.
Someone points out that I shouldn't be storing passwords in plain text so I want to store them hashed.
Despite there being hints in the documentation that this is possible (migrations shows the password hashed), it's not clear how to carry out this kind of change.
A walkthrough of making a change would help convey the use case much better than just templates of "this incantation produces this output".
Well, in this particular case passwords are always hashed. So the platform deals with that for you. Other changes to the data model need a migration, which is covered here: https://alan-platform.com/pages/tuts/migration.html
Is this defined anywhere within the project or is this framework magic? (Or "glue" if you don't like the term magic). password is not mentioned again anywhere in the documentation, I'd like to understand how the framework knows to hash the input.
The line `password : . 'Password'` points at the password property, which tells the framework to hash it. What kind of hashing isn't something you should have to specify or worry about. It's a strong salted hash and we'd like to make it even better at some point, but that's firmly in the realm of the framework implementation.
I think you may have some issues persuading customers that's a wholly valid approach, especially when you're dealing with security and data integrity, GDPR, and so on.
It looks like you're using SHA256(username||password) in this example. Even if it's only an example, why use a homebrew password hashing scheme based on an unsuitable hash function and bad ad-hoc salt handling, instead of a strong standard password hash with built in salt handling? And what code/specification is required to use a secure algorithm, like bcrypt with a random salt?
People often copy from such tutorials and will then end up with insecure password storage.
As someone who's not a developer but still occasionally looks through these "build an app" tutorials, password/authentication portions always worry me. I wish I could know that best-practices were shown as far as storing/encrypting user data/passwords.
There is a lot the platform can do by itself, but I think you grasped it well enough. The side loaded apps are definitely the escape hatch to enable things it doesn't cover (yet).
Graph databases are much more powerful and a better fit for our modeling language. However, the platform can create a live SQL database mirror if you need that kind of thing.
One database runs one model (multiple databases can be connected to each other via interfaces). One transaction can update any number of properties, collections, etc.
Can you comment a bit more on what makes graph databases such a good fit for you? As far as I can see the models seem to fit pretty much 1:1 to a relational model?
I have experienced low-code platforms, and to me your approach looks very well thought-out! Veel succes ;)
We're still feeling out the market here, to see where we can take it. It will probably stay free for personal use and then grow from there with services like hosting, etc. Pricing model for businesses is something we're looking at from case to case currently.
Competitors include Mendix, Outsystems etc., when it comes to low-code and serving citizen developers. Excel as well. On the other hand there are still a lot of custom implementors out there that try to solve similar problems for businesses.
That's helpful...thanks. I had been very interested in Google's Appmaker (https://developers.google.com/appmaker/), but their model where only paid Gsuite users can access applications was a showstopper, as it made access to the general public impossible.
Really interesting framework. And the docs are super easy to understand; nice work!
I'll be interested to see where it goes with pricing. It's hard to start building on a platform if you don't know if it's going to become too expensive in the future.
Paid hosting seems like it would work really well for a system like this (though I'd encourage some type of open-core model as well, so people have some escape hatch if the company goes under).
Good to hear the docs are clear for someone who hasn't been "living it" for years.
I understand it's hard to put your trust into something Alan right now, so we're definitely looking at making more of it available without our direct involvement.
All I can say right now is that you should just give it a go, I bet it will change the way you look at code. If you do eventually want to build something critical on Alan, get in touch with us and we'll get the contracts set up to support that properly.
I would also like to see this comparison. Another thing is; HN is really the wrong audience for this. Technologists here will spin up a vm/container with their stack of choice. Indeed; ruby and rails, django, node, all fill the void 4GLs did decades ago.
Finding and reaching users for this type of tool is the challenge imo. Implementation is the easy part.
We anticipated that HN wouldn't be a perfect fit, but it's a critical audience and usually open to something new. It needs to become more mature before mass adoption amongst citizen developers and exposure to the developer community is one way to make some steps in that direction.
I dunno. This is exactly the kind of thing I come here for. Even if I never use it myself, it's an idea I've thought about myself, so it's good to see someone else made it.
4GL solutions are one way to attack the problem of scaling and maintaining large applications. However, you tend to end up with a traditional code base and a relational database, without a strong core specification. Especially once you start customizing an application like that, you run into the same problems as a 3GL stack.
Alan plays a longer game, with a drastically different approach to specification and development of applications of any level of complexity. Models drive everything and you can't look "under the hood" to look at or modify the implementation. Even at the level of the platform itself, models and code generation drive down the amount of 3GL code we have to deal with. WYSIWYG editors and drag-and-drop UI builders aren't a starting point, it's something we might grow towards supporting in the future.
Hey Koen, congrats on you and Corno making front-page on HN!
I can definitely confirm for others reading this that it indeed has been something like 10 years in the making; I was working with a prototype of it 8-9 years ago and found those data models so nice that I actually reimplemented the core idea in a repository on GitHub, though it didn't really go anywhere except for my own web site. I have also been able to reimplement it in TypeScript more recently, so that there is a non-Turing-complete subset of algebraic data types (though maybe I'll be able to add a fixpoint operator, who knows) as runtime objects with highly specific TypeScript types that are inferred from the functions you use to construct them. So then a parametric TypeScript construct,
ValueOfType<typeof mySchema>
embraces values that match the schema that you just specified. You can use this trick to write functions like
myHTTPRouter.get('/objects/by-id/:objectguid', {
params: {
objectguid: {
type: 'guid'
}
},
async handler(params) {
// inside of here, params has type {objectguid: string},
// and VSCode knows this, because params is ValueOfType<schema> where
// the schema is specified in the `params` key above.
return response.json({success: true})
}
})
It's a really fun perspective on programming to have these schemas available at both runtime and compile-time, very DRY.
Hi Chris, how are you!? It's been a while man. We've definitely dug into it a lot deeper than last time you worked on it. As you say, once you get how the models work it sticks with you :)
I've been well. Landed a software job with a company called IntegriShield doing a sort of internet rent-a-cop work, now am writing apps for a mechanical contractor called US Engineering -- turns out the construction business always runs on razor-thin margins which is kinda nice because, like, reducing cost by 1% when construction margins are only ~5% causes a 20% improvement in net profit.
This is great work, and I think you're burying one lede, which is that it looks like you've embedded a declarative permissions model in this thing, and I built one of those and the time saved can be huge when authorization is handled at the model level rather than everywhere in the business logic.
The permission model actually only landed a few weeks ago, so we haven't been able to fully appreciate what we did ourselves. You're right though, it's probably a pretty huge deal :)
I don't think TypeScript has a native GUID type, but if I am wrong about that please tell me as it will make my code more type-safe.
The `string` type here comes from a mapping that the router is using. That is, the router ultimately type-evaluates a `ValueOfType<{type: 'guid'}>` to `string`. But because it's a runtime object, the router can also, at runtime, validate that URL param, "did they actually give me a UUID?" -- and sanitize it, e.g. "convert all UUIDs to lowercase."
(In fact the benefit of having this TypeScript type at runtime is even bigger than that. With Express.js, the router can rewrite the route param so that the route doesn't even match if you don't provide a UUID, which matters because there is often a lot of accidental ambiguity in HTTP APIs -- but here you can embed the UUID regex into Express paths. The router can then also do some other trickery like confirm at initial load time that all params in URLs match params in this `params` dict, and it can convert all of its routes to OpenAPI/Swagger docs so that you can define another route which just gives you your OpenAPI JSON. Literally in what I have written the above would be a type error because the `Router` class would complain that `params` has the wrong type because the `objectguid` descriptor needs a key called `doc` which is a string for parameter documentation for OpenAPI.)
Thank you for the example. I just don't want to be picky but that is church encoding. To represent a number, say 1234567, you will need million items in a list.
Ah, like that. It's a fair point, but you're interpreting the model at too low a level. You don't have to model all possible values of scalar types (number, text) because the implementation of all possible values is known. I.e. you're writing a model that will drive the behavior of the application in terms of business rules, with specifications that matter to users of the application.
In your project, you write specifications. These are read by the runtime components (database, web client) and this specification fully defines their behavior. There is no project specific code, everything you can write in your data model is supported by the runtime components. You can look under the hood at that level, the runtimes are built in C(++) and TypeScript etc., but it's completely generic. In fact a lot of that codebase is generated.
I like that this picks up where excel drops off. But I would like to see some concrete examples. Someone here mentioned a video, that would be good, or even just a list of several specific use cases.
Also 'can-create:' and 'can-update:' seem to always have some shared logic. Instead of:
can-create: user +'Roles'?'Manager'|'Yes'
|| user +'Roles'?'Project Manager'|'Yes'
can-update: user +'Roles'?'Manager'|'Yes'
|| user +'Roles'?'Project Manager'|'Yes'
|| equal ( user , $ >'Project Group'>'Owner'>key )
You could do something like:
can-create: user +'Roles'?'Manager'|'Yes'
|| user +'Roles'?'Project Manager'|'Yes'
can-update: &can-create || equal ( user , $ >'Project Group'>'Owner'>key )
I feel like there should be a link to a demo application more easily accessible. I'm interested in what type of things I could build with it, is the only way to check that out forking the tutorial repo and building it etc?
I liked the developer experience right off the bat -- the way the data structures are modeled couldn't be more elegant.
However, this put a crimp in my enthusiasm:
"[Alan] defines all possible states of the data, and in effect all possible states of your application"
We recently finished refactoring a complex algorithm that got away from us because we coded it as a state machine rather than a plain vanilla algorithm using good old sequence + iteration + selection. The state machine version may have been easier to write, but the old fashioned algorithm was so much easier to reason about and maintain.
Both approaches have their place. If the problem you're solving is best served by an "old fashioned algorithm" you can hook up a side application to your core system. The interface you define between the side app and core ensures your data never gets into a weird state because your algorithm didn't cover a case. For instance, for some projects we hook up to the Preactor planning system specifically to use their algorithms.
Any thoughts of totally revamping the syntax of this declarative language? Perhaps borrow some inspiration from Ruby or some other humane english-like programming language?
What's the point in forcing non-coders to write "-> {}" multiple times for no reason?
As for Ruby, you can be like Matz and strive for happiness by minimizing syntax and maximizing readability.
175 comments
[ 2.5 ms ] story [ 175 ms ] thread> Instead of the traditional relational database + 3GL or 4GL language, the core of Alan is a data modelling language that automatically generates full stack applications.
If you'd like to know more, we'll be monitoring this HN post and we have a forum: https://forum.alan-platform.com
This is the correct link: https://alan-platform.com/pages/tuts/getting-started.html
I’m not doing the tutorial.
I’m sufficiently interested to give it a 30 second video. If that looks interesting I might look at more involved videos about some aspect.
The flow is pretty bare bones though, so if you're used to a text editor and command line tools it'll be pretty familiar.
In your shoes I’d turn around and make a 1 minute video and upload it to YouTube within 20 minutes, showing what your system is and what these data structures look like.
If you have an Apple Mac, the screen recording is built right into QuickTime, just plug your telephone headset into the machine to record some narrative as you go.
Seriously, why launch without showing people what it is? 10 years coding, not willing to spend 5 minutes to record it and show us?
I’m not interested in reading about the deployment process. Really not.
Sell me on what you made.
I think the focus should be meeting the needs of actual customers. And an intro video for people who are still deciding if they will give a chance is not one of those needs by definition.
Right after launch, you want to iterate the product for your actual users. After-launch is not growth phase, is product/market fit phase. Some friction that filters out customers that are not of the early adopter profile might even be desirable.
The only exception is if you do not have enough customers to get feedback from, then you work on this sort of thing.
An important, if subtle, point is that I am not against sales in this early stage, I am all for it. I am against investment in inbound growth-only tactics. Founders doing early sales can both overcome any deficiency in a landing page, learn about what is the best message, and improve their product along the way.
In that sense trying to appeal to people that would potentially use your system sounds like a great idea.
I'd love to. You need to show it on this page.
Even if a screenshot (or screen capture, or some code) is pretty useless, it helps give the right context, and tells me this is actually a thing, and not just a hope.
This [0] should be front and center.
[0] https://alan-platform.com/pages/tuts/helloworld1.png
However, the logo to me did look like a blood bag with some yellow liquid in it and two tubes sticking out at the bottom. (When shown on white background, you cannot see hair on the guy's head - https://alan-platform.com/pages/tuts/introducing.html ) Anyway, the program looks very intuitive in its purpose and goal!
It's the process of laying down the rules for the data in your application that drives development in Alan. Unlike Google App Builder, you don't start from a drag and drop UI builder. Although a drag-and-drop UI builder is something we might want to add at some point. For most applications though, the generated UI is plenty powerful, because what it needs to support is perfectly specified in the datamodel.
If it is, I think it is a very welcoming innovation. I believe there are a lot of use cases in business that are currently under-engineered into Excel or over-engineered into complete web apps, SAP or salesforce applications.
BTW, it is a mystery to me why MS Access itself, that is still around, lost this post.
As you say, we see Excel being stretched to doing things it cannot do, and on the other hand custom apps being built for things that don't need to be so specific. There is a place for low code the way Outsystems does it for instance, but we believe a lot of businesses would be better served by something like we're offering here.
* How do I model business rules? How do I model a State machine?
* How do I connect with external APIs systems?* You mention that you have an ERP system based on this platform. Can we look at that code? Can we have some testimonials?
Kudos: * It's good that you are doing a declarative approach to business software... this is still most of the software we use and I don't think it's a solved problem.
* On using a Graph database I think this is better to model complex domains. However which graph database are you using? Neo4j, Dgraph, OrientDB or is an inhouse graph database?
* On the name
I expected that as well from the title but at the very start they link the meaning of the term so that those of us that don’t know what it means can quickly find out on Wikipedia.
I think it’s best to do like they are doing and link the Wikipedia article.
I’m more curious as to the name Alan.
Alan is definitely related to model driven engineering. It's a different take on what a model can specify, and models drive everything we do.
https://www.m-industries.com has some testimonials. We can't share those particular data models, but if you're really interested get on the forum and we can dig into some of those areas.
External systems can be interfaced with using our bridge application that can work with relational databases. We have tooling to rapidly build custom connectors using our interface specification language. One area that Alan shows it's still early days is that we don't have a shelf full of ready made connectors.
Our stack is all home grown. We run on a tiny custom built Linux distro. The graph database is also in house. There wasn't anything out there that fit our needs (like being 100% push/subscription based). Luckily Alan also helps keep our line count pretty low throughout the stack.
No one else has heard of it.
Let's say I want to develop a multi user todo and I've followed the examples and now have some Users who log in entering a password.
Someone points out that I shouldn't be storing passwords in plain text so I want to store them hashed.
Despite there being hints in the documentation that this is possible (migrations shows the password hashed), it's not clear how to carry out this kind of change.
A walkthrough of making a change would help convey the use case much better than just templates of "this incantation produces this output".
/* 'Users': collection { 'Password': text }*/
How does the platform know to hash that? Is it looking for magic property names?
So to clarify, it's this password: declaration which tells the framework to hash the input?
Is this defined anywhere within the project or is this framework magic? (Or "glue" if you don't like the term magic). password is not mentioned again anywhere in the documentation, I'd like to understand how the framework knows to hash the input.I think you may have some issues persuading customers that's a wholly valid approach, especially when you're dealing with security and data integrity, GDPR, and so on.
People often copy from such tutorials and will then end up with insecure password storage.
I doubt they will ever care about any of that. a "side loaded application" will likely be the answer to most of those comments.
I have experienced low-code platforms, and to me your approach looks very well thought-out! Veel succes ;)
Competitors include Mendix, Outsystems etc., when it comes to low-code and serving citizen developers. Excel as well. On the other hand there are still a lot of custom implementors out there that try to solve similar problems for businesses.
I'll be interested to see where it goes with pricing. It's hard to start building on a platform if you don't know if it's going to become too expensive in the future.
Paid hosting seems like it would work really well for a system like this (though I'd encourage some type of open-core model as well, so people have some escape hatch if the company goes under).
All I can say right now is that you should just give it a go, I bet it will change the way you look at code. If you do eventually want to build something critical on Alan, get in touch with us and we'll get the contracts set up to support that properly.
https://en.wikipedia.org/wiki/Fourth-generation_programming_...
Finding and reaching users for this type of tool is the challenge imo. Implementation is the easy part.
Alan plays a longer game, with a drastically different approach to specification and development of applications of any level of complexity. Models drive everything and you can't look "under the hood" to look at or modify the implementation. Even at the level of the platform itself, models and code generation drive down the amount of 3GL code we have to deal with. WYSIWYG editors and drag-and-drop UI builders aren't a starting point, it's something we might grow towards supporting in the future.
I can definitely confirm for others reading this that it indeed has been something like 10 years in the making; I was working with a prototype of it 8-9 years ago and found those data models so nice that I actually reimplemented the core idea in a repository on GitHub, though it didn't really go anywhere except for my own web site. I have also been able to reimplement it in TypeScript more recently, so that there is a non-Turing-complete subset of algebraic data types (though maybe I'll be able to add a fixpoint operator, who knows) as runtime objects with highly specific TypeScript types that are inferred from the functions you use to construct them. So then a parametric TypeScript construct,
embraces values that match the schema that you just specified. You can use this trick to write functions like It's a really fun perspective on programming to have these schemas available at both runtime and compile-time, very DRY.This is great work, and I think you're burying one lede, which is that it looks like you've embedded a declarative permissions model in this thing, and I built one of those and the time saved can be huge when authorization is handled at the model level rather than everywhere in the business logic.
The permission model actually only landed a few weeks ago, so we haven't been able to fully appreciate what we did ourselves. You're right though, it's probably a pretty huge deal :)
The `string` type here comes from a mapping that the router is using. That is, the router ultimately type-evaluates a `ValueOfType<{type: 'guid'}>` to `string`. But because it's a runtime object, the router can also, at runtime, validate that URL param, "did they actually give me a UUID?" -- and sanitize it, e.g. "convert all UUIDs to lowercase."
(In fact the benefit of having this TypeScript type at runtime is even bigger than that. With Express.js, the router can rewrite the route param so that the route doesn't even match if you don't provide a UUID, which matters because there is often a lot of accidental ambiguity in HTTP APIs -- but here you can embed the UUID regex into Express paths. The router can then also do some other trickery like confirm at initial load time that all params in URLs match params in this `params` dict, and it can convert all of its routes to OpenAPI/Swagger docs so that you can define another route which just gives you your OpenAPI JSON. Literally in what I have written the above would be a type error because the `Router` class would complain that `params` has the wrong type because the `objectguid` descriptor needs a key called `doc` which is a string for parameter documentation for OpenAPI.)
And there would be some kind of transition in-to or out-of that third state that would specify the addition.
However, this put a crimp in my enthusiasm:
"[Alan] defines all possible states of the data, and in effect all possible states of your application"
We recently finished refactoring a complex algorithm that got away from us because we coded it as a state machine rather than a plain vanilla algorithm using good old sequence + iteration + selection. The state machine version may have been easier to write, but the old fashioned algorithm was so much easier to reason about and maintain.
The ASCII art isn't rendering correctly. (In Chrome on a tablet.)
Which is odd, because that's a mono-space font, I'm sure.
Most probably a font issue.
What's the point in forcing non-coders to write "-> {}" multiple times for no reason?
As for Ruby, you can be like Matz and strive for happiness by minimizing syntax and maximizing readability.
Any relation to the defunct Microsoft Oslo/M-Language model-driven development platform?