There's a framework for C now at https://vely.dev which may help with C strings safety and memory management, among other things.
HN user
dsvr
Simpler way to parse JSON in C with Vely framework.
See how to get a JSON request from the web, either from an HTML form (via POST) or JavaScript (application/json) request body.
The example shows parsing JSON in two different ways: traversing the whole document, or extracting the exact fields you need.
The example is a list of cities, within states, within countries.
Disclosure: I am Vely's creator. - Sergio
Here's an example of how an existing (and maybe the oldest?) language but with "new armor" can significantly lower the carbon footprint:
Writing Green Software - Is Our Code Unfriendly to Environment - https://dev.to/velydev/writing-green-software-is-our-code-un...
Vely is a framework for C developers.
Improvements in Vely 13/12:
- Bunch of examples, including multitenant SaaS Notes application in only about 300 lines of code.
- Added JSON support.
- Added UTF8 support.
- Added Hash table support.
- Added cache for super fast REGEX pattern matching and replacement.
- Simplified SQL queries for a clean simple interface.
- Source files now have .vely file extension to make it easy to recognize Vely code.
- Building applications now has automatic library inclusion.
- Lots of bug fixes.
See release notes at https://vely.dev/release_notes.html for details.
I've incorporated it in "In a nutshell" section on the front page. Hope it helps people get what Vely does right away.
That is a very interesting suggestion. The API underneath is already well-defined and documented in code. Something to consider for sure.
In this case, just check if there is, near the beginning of file:
#include "vely.h"
which has to be in every Vely .v file.
That is one of the use cases I would say are perfect for Vely. A combination of a low-level and high-level approach, which is often needed, and not just in this arena.
IOT (Internet Of Things) is a major application area for Vely. Obviously what you mentioned may fall into that. But also for example IOT-edge systems, where the communication with multiple near-devices converges, gets processed and then delivered to a cloud server for congregation.
Thank you for this feedback. I really appreciate it. I will incorporate it prominently on the web site.
I guess you could say that. Quite a few comparisons here, and none really wrong as it's all in the eye of a beholder. Vely's main goal is to give you building blocks for general purpose application development, especially including web applications.
Vely statements are created to generate safe code that will take care of memory issues you mentioned. It's like using a library that does something for you safely, except that Vely provides an interface that is more flexible and easier.
The trick is for Vely to be rich enough to provide the functionality that's typically needed. That is its goal. I hope it's far enough along to be useful, and with time it will get even more so.
Generally, the memory used by Vely statements is created by Vely and you don't have to free it, in fact you shouldn't, it will be freed automatically, even if those pointers are lost or overwritten. The approach is to drastically minimize using C's allocation, and do that only when absolutely necessary, which for most applications should be never.
However, you can still write any C code that does horrible things with memory. Vely exists so you don't have to. The idea is to use Vely to write code that you might otherwise write in pure C and have those issues.
At the time I didn't know that. Perhaps .vely extension, I guess that would do it. Something to consider to be nice for sure. Thanks for that.
I didn't know about Vlang, I checked it out, looks very cool.
Vely is really not a language breakthrough. Not at all.
I would say Vely is a practical workhorse. It is about power of rapidly doing business. Kind of like PHP but more in a declarative way like SQL, within C.
As in, you need a collection of libraries that do all the stuff you need to build an application (run queries, build strings really easy, execute programs, do web calls, deamonize programs etc.).
And you need it without writing C code or using API or procuring libraries and header files, but rather you'd just spill your thoughts about what to do in a language that sounds like a natural language, where even the order of how you say it isn't that important.
Yes, kind of, you're right. C++ though went on for a roller-coaster of complexity, at least that's how I see it.
I think of Vely as staying simple, declarative, and C all the way for performance reasons. More of a collection of practical things you'd want to do.
I see your point. That's something to add to the documentation. For now, I guess, here it is. Each Vely statement generates some C code, maybe a one-liner, maybe quite a few. It works kind of like a declarative statement, SQL comes to mind. Some clauses in a Vely statement are input data, others are output. The generated code will take the input and fill in the output.
And Vely generates a request dispatcher, which takes the "req" input parameter, which is really the name of the source Vely file. So if "req=mycode", then the function "void mycode()" will execute and it must always be defined in source file mycode.v. This makes it easy to always find the code, and quickly grasp what application does.
Unlike C Makefile, you don't have to write a Makefile. Whatever .v files you have in your source code directory will be automatically picked up and made into an application.
The generated code can and will change. It tries to do the best job of doing what is instructed to do. So if you say:
web-call "http://website.com" response resp response-code rc status len post files "file1"="uploadtest", "file23"="fileup4"
then it will generate the C code to effectively POST a form to website.com that sends two local files to that server, and will get you the response code and status back. You can do this by using CURL library, but it will take quite a bit of C coding to do this. And there are many different combinations and things you can do, and the code gets generated to do it quickly and efficiently.The same goes for exec-program, run-query, send-file, encrypt-data etc etc. All this things you can program yourself in C, but these statements are flexible and will let you quickly and safely do those things. More like "what I want to do" rather than "how I want to do it". Though, like I said, you can examine the generated C code to see exactly how it's done.
The "hello world" tutorial is good for this. And if you do decide to try Vely, I would say try
https://vely.dev/123_hello_world.html
first, as it can't get any simpler. It's designed to give you an application in minutes. You'll get a command-line executable, and you will be running your own application server that can take input from Apache or Nginx via FastCGI. The example though uses FastCGI command line client so you don't have to do anything beyond what's already included in Vely package.No, Vely does not understand C. Yes, gcc produces error messages when it comes to C code itself. However, the line number where the issue is located is exactly matched to the Vely source code using #line directive, so I would say 90+% of the time you don't have to look at the generated code. If that is not enough, you can use --c-lines to get the error reported from generated code, which is the exact error, and in that case, yes like you said you need to look at the generated code. Most of the time, however, just looking at the exact embedded statement is enough to figure out what the problem is.
I mentioned in another post that a C program could be parsed to the extent to allow better checking. Not to the point where you'd build a gcc-look-alike, but just enough for instance to know the type of the expression, and if the expression used in Vely statement is correct, and such. Perhaps that's something to consider. I thought about it here and there, but found it to be more useful to check for logical conflicts, such as not providing required arguments, balancing beginning and end of multi-part statement, incorrect usage and such. Typically, using the wrong type accounts for most of the issues, and gcc produces very good messages. Again those messages get matched to the source Vely file exact line number, and I found that correcting an issue isn't difficult.
Your tool sounds great, and if it works what you need it do, awesome! I do things like that all the time, and find that often times using tools is an overkill, and just skip it. There's time and place for everything.
Ha ha, okay you got me. It's a piece of code that is for demonstration only. But I needed a simple piece of code that speaks of shrinking, without making the front page an exercise in design patterns.
I changed the indentation of lists to be smaller. At first just for mobile via media CSS, but then it seemed more readable for desktop too. So it should look better now.
I found DejaVu Sans Mono to be a bit thinner and easier on the eyes. Either way is fine really. One of those whimsical decisions, I guess.
It is fixed. Thanks again.
Great suggestion, thanks. Will do.
Figured out on the fly hackernews markdown. Pretty neat.
Thanks for your feedback. You can see the equivalent C code for any statement pretty easy. For example, if you go to "tutorials", then "tutorial-stock_app", and follow the tutorial instructions, you can always see the generated C code, which would be in:
/var/lib/vv/bld/stockapp/__stock.o.c
(so here "stock" is the application name and there's "stock.v" file).For example, when you see this Vely statement in stock.v (which obviously obtains input parameters from either GET or POST request):
input-param stock_name
this is line 9 in stock.v.All you need to do is look for:
#line 9 "stock.v"
in the generated code (which is
/var/lib/vv/bld/stock/__stock.o.c), in this case it's: char *stock_name = vey_get_input_param (vey_get_config()->ctx.req, "stock_name")
So in this case, it's just one line of C code. In other cases, it may be many lines. For example, Vely statement which apparently runs the INSERT SQL query: run-query#add_data@db = "insert into stock (stock_name, stock_price) vaues ('%s', '%s') on duplicate key update stock_price='%s'" : stock_name, stock_price, stock_price
This is on line 12 in stock.v, and you can simply search for #line 12 "stock.v"
in /var/lib/vv/bld/stock/__stock.o.c file. In this case, the generated code looks like: VV_UNUSED (_column_count_add_data);
vely_get_config()->ctx.db->ind_current_db=0;
static void *_sql_prep_add_data_stock_v_649 = NULL;
_is_input_used_add_data[0]=1;
_is_input_used_add_data[1]=1;
_is_input_used_add_data[2]=1;
add_data = "insert into stock (stock_name, stock_price) values ('%s', '%s') on duplicate key update stock_price='%s'";
const char *fname_loc_add_data = "stock.v";
num lnum_add_data = 12;
vely_location (&fname_loc_add_data, &lnum_add_data, 1);
vely_make_SQL (&_sql_buf_add_data, 3, add_data , _is_input_used_add_data[0]==1 ? (stock_name) : NULL , _is_input_used_add_data[1]==1 ? (stock_price) : NULL , _is_input_used_add_data[2]==1 ? (stock_price) : NULL );
if (_qry_executed_add_data == 1) {vely_report_error("Query [add_data] has executed the second time; if you want to execute the same query twice in a row without a loop-query, use different queries with the same query text (or variable) if that is your intention, file [stock.v], line number [12] ");}
_qry_executed_add_data = 1;
vely_execute_SQL (_sql_buf_add_data, &_arow_add_data, (const char**)&_err_add_data, (const char**)&_errm_add_data, 0, 1, 0, &_sql_prep_add_data_stock_v_649, _sql_paramcount_add_data, _sql_params_add_data);
_nrow_add_data=0;
vely_db_free_result ();
vely_free (_sql_buf_add_data);
so about 16 ines of code.This way you can see what actual C code is generated for any Vely code.
And you can also step through this code in gdb by using --c-lines option in vv.
Thanks a bunch! I will look into this.
But I guess from a bird's view point, I can see how all the impressions given here are correct. It does look somewhat like PHP for C or like a markup language, or a declarative language etc.
There's some truth to all of that to some extent.
I guess you could see some similarities. Vely is standalone though, not an extension. And it is 100% C, always creating native executables.
By that I mean a direct native executable from either pure C or embedded statement producing shallow and performant C, without layers of other languages intertwined (because in the end anything is always a native executable even if it has layers of byte codes, interpreters, alone or mixed with native extensions).
"Vely" stands for Vel(ocit)y. Though I then realized in Korea it's short for Lo(vely). Could be worse.
I am into grilling and griddling and cooking, so comes natural to me :>
Thanks for the feedback, I appreciate it. Yes, Vely does not parse C. Placing Vely statement outside of functional context (say in between functions) will result in gcc errors. Vely allows error reporting to show both generated C or line numbers in Vely code, so depending on what the error is, it's not that difficult to find.
Making Vely understand C, at least insofar as necessary to prevent issues like this is something that I might add, and it probably wouldn't cost that much. It's definitely worth a look.
From a purely functional perspective, assuming Vely statement is placed properly in a functional context, understanding C (as in parsing and then parsing Vely within) might not bring much benefit. Syntactically speaking, Vely is built to not require much about host language. Though, Vely understands enough to emit meaningful messages, such as in the case of writing:
if (cond) vely_statement
where you will get an error that will prevent code from doing unexpected things. There's quite a few of those safeguards built-in.
Being embedded, Vely is a compromise. That was the goal to preserve pure C performance.
Beyond the above, one can still do anything that C can do and that may not be safe; but if Vely is used for what it does, the chances of that go down. Being able to rapidly do stuff in C that is richer and safer is the plus side of it. Without a compromise with being embedded, it would be yet another language that does everything great but with ever declining performance.
And that is fine, if such loss of performance and increased footprint is acceptable; there is nothing wrong with that. Vely's niche is to stay in best performance bracket, and yet bring that performance to general and web application development.
I looked at kcgi and it's pretty cool for CGI/FastCGI if you want a-la-carte and then you use separate libraries for everything else.
Vely has FastCGI built in by default (you can start FastCGI server in seconds with vv/vf), and the output statements (such as @ or p-out) do output to the web (i.e. to the Apache or Nginx reverse proxy) by default.
So you could say in terms of functionality, kcgi is built into Vely transparently.
In terms of additional functionality beyond kcgi, Vely offers
- web constructs (getting input parameters from GET/POST, uploading files, sending files to client with send-file, cookie handling, output to web etc.),
- safer and easier string manipulation,
- database access (mariadb, mysql, postgresql, sqlite) with prepared statements and persistent connections,
- regex (match-pattern),
- exec-program for executing programs,
- file operations,
- encryption/encoding/hashing.
I agree there's a learning curve. I can't say how would people see that, though the idea is to be easier than a traditional API, simply on the account of writing a single statement instead of say 5-10 C API calls.