Hacker Newsnew | past | comments | ask | show | jobs | submit | graboid's commentslogin

As someone really tempted to use SQLite in production, the one thing I keep bumping against is how to have a nice GUI to interact with the running database. With our current prod databases, I can connect dbeaver and the like to them and nicely browse the data, query, or even do the occasional fix. Seems like this would be much more of a head scratcher if the database is just a file on the same VPS the app runs on.


DBeaver can also open/manage SQLite databases. I use it daily (although on a tiny page).


Ah, my point was more on how to connect to the live database on some remote server.


DBeaver can connect to remote sqlite databases through an SSH tunnel:

https://dbeaver.com/docs/dbeaver/Database-driver-SQLite/#rem...


Connect to the remote server and run it?


If your app is a web app you could create a rudimental page with SQL input and table output and authorize only admins. It's risky, if someone gets access to admin account they can drop everything. I have something like this for logs, app reads log files directly and they are accessible only via private domain (tailscale), if I connect to public domain I can't access logs. Additionally you could enable only SELECT statements via web.

Another downside is that it will take time to make it look nice.


sqlite-web, put it behind nginx with basic auth or configure a password.


I feel for a smallish project I'd rather prefer to have more readable, dense code like Ruby's over the ceremony of static types.


There is almost no ceremony involved in dealing with types in Rust.

And what little there is, is worth it ten-fold for all of the runtime bug headaches that you avoid compared to dynamically typed languages.


Specifically addressing the "almost no ceremony" claim and not the "totally worth it" claim:

JS:

  let person_1 = { };
  let person_2 = { parent: person_1 };
  person_1.child = person_2;
Rust:

  use std::cell::Cell;
  struct Person<'a> {
      parent: Option<&'a Person<'a>>,
      child: Cell<Option<&'a Person<'a>>>
  }

  let person_1 = Person {
      parent: None,
      child: Cell::new(None)
  };
    
  let person_2 = Person {
      parent: Some(&person_1),
      child: Cell::new(None)
  };
    
  person_1.child.set(Some(&person_2));
And that's before we start talking about function signatures and traits.


Sounds cool, as someone interested in concatenative languages and also a user of C#, might I ask if you have a link?


Factor is super cool! And the amount of packages ("vocabularies") it comes bundled with is just astonishing.


I assume that in most array languages, you also create "words" or however you want to call functions, to reuse code. I wonder about a purely aesthetic issue: how does it look to interleave those symbols with user-defined words that by nature will be much, much longer, i.e. "create-log-entry" or "calculate-estimated-revenue".


I never did any real programming in APL, but I studied it over about 2 months. When you get used to the symbols, reading spelled-out words feels like reading in slow motion, or being stuck in molasses.

Most (not all) APL code I've seen uses very short names, often one letter names, for function names. And APL programmers are famous for cataloging "idiom" which are short phrases for common subroutines. In other words, it's best practice to repeat 3- or 4- symbol phrases instead of defining a subroutine.

Of course, there's nothing about an array language that requires using symbols; but for some reason most do.


>Of course, there's nothing about an array language that requires using symbols; but for some reason most do.

The idioms become words and you read them like words, you don't step through each letter of a word when you read it, you recognize the shape. The same thing happens in APL and its ilk, any commonly used sequence is instantly understood as its function without having to parse each individual symbol and what it does.


Yes the symbols in a way are the letters of APL, and the phrases are the words.


in k, we say "primitive operators are verbs", and "lambdas, functions, variables, literals are nouns".

higher-order functions (over, scan, each, etc) are called adverbs.


> i assume that in most array languages, you also create "words" or however you want to call functions, to reuse code.

sure, that's a very useful feature, like elsewhere.

> I wonder about a purely aesthetic issue: how does it look to interleave those symbols with user-defined words that by nature will be much, much longer, i.e. "create-log-entry" or "calculate-estimated-revenue".

strictly speaking, dashes and underscores in k can't even be a part of identifier - they are core language primitives. it is very uncommon to see java-like identifiers like CalculateEstimatedRevenue, why would you want that?

to your question:

here's a bit of an oddity: all user-defined functions and core language operators can be called using functional notation:

  v:1 2 3        / some vector
    v+v          / usual infix notation, two operands: left and right
  2 4 6
   +[v;v]        / same as infix, but called as it were a function.
   2 4 6

  add:{x+y}      / a user-defined function: a lambda with a name and two operands.
  add[v;v]
   2 4 6
but there is an important distinction between the two. you can't use your `add` function infix, you must call it as a function, and there are good reasons for that:

  2 add 2         / that's not gonna work
that said, mixing language primitives with function calls looks and reads just fine:

  +/add[v;v]
 12
hope this helps!


How does that scale up to program that's thousands of lines? What if you have a hundred different vectors? You're not going to be calling them v1, v2, ...

So does it end up as

    v_sepallength: 11 14 12
    v_sepallthickness: 1.3 1.5 1.2
    mul[v_sepallength;v_sepalthickness]
Or, do you just not do that sort of stuff in these languages? I'm not very familiar with them, but I have ended up with some pretty long programs using Pandas in Python.


> Or, do you just not do that sort of stuff in these languages?

i tell you more. it is very much recommended to avoid doing this sort of stuff in all languages.

  v_sepallength: 11 14 12
  v_sepallthickness: 1.3 1.5 1.2
  mul[v_sepallength;v_sepalthickness]
no:

   /sepal:lengths and stroke widths
   spl:[l:11 14 12;w:1.3 1.5 1.2]    /this is your "struct", if you will
  
   spl.w
  1.3 1.5 1.2    /proof

   */spl
  14.3 21. 14.4  /for mul, we don't even have to bother with field names

   */spl`l`w     /but if you insist, lets make it explicit
  14.3 21. 14.4

to produce a "factory" for well-formed spl objects is a no-brainer as well.

why we don't use v_ prefix:

  1. everything what can be a vector should be a vector.
  2. we can't use underscore anyway - it is an operator.


very important things should have short names. locals you're immediately operating upon should have short names. short names should be used in a consistent way.

less important things can have longer names. variables in a broader scope can have longer names.

if you have a hundred different vectors, don't just dump them in a pile; put them in dictionaries, tables, namespaces, or scopes.


exactly.

the complexity is built differently in k.

  * namespaces do exist, and are just as useful as they are in c++ and especially my beloved *sun.misc.unsafe*. i recommend.

  * instead of passing 20 arguments to a function (which is impossible - the limit is lower), we pass a dictionary if we have to. k **pretends** that everything is passed by value, but in reality it is much smarter than that.

  * notion of *scopes* is a bit of a non-sequitur here, but it is fundamentally important that there is no *lexical scoping* in k. the only two scopes which are available from the scope of a lambda are exactly *local* and *global*. and for as long as your function doesn't mess around with global scope or i/o (which is essentially the same thing), it remains pure, which is super cool. this design is not just for simplicity - it is for a good reason, and more than one.

  * the above doesn't mean that it is impossible to create a *closure* in k and pass it around as a value.

  * functions take up to three implicit arguments - named x,y and z (they can be renamed explicitly, but why not just document their semantics instead, in-situ?). all you need to do to declare xyz is reference them in the function definition. in competent k code, you'll rarely see a function with more than xyz.

 * in k community, we don't use upper case unless the apartment is on fire. god forbid.

 * shorter names and more documentation, and there will be joy.


It depends on the language and the programmer.

https://github.com/mlochbaum/BQN/blob/master/vm.bqn


It is a very interesting write-up. A random thought I had while reading this: I feel like long-term, a system that schedules/"optimizes" the process of learning by reading/watching content and then engaging with this new content by taking notes and connecting those notes to existing knowledge could be more fruitful. Something akin to SuperMemo's "Incremental Reading", but not as focused on creating flashcards out of the material.

With traditional Q/A-style spaced repetition, I feel like accumulating a long list of isolated facts sometimes (I know, you can remedy this a bit by also quizzing connections, context, but I feel like the general tendency still remains).


Did you learn that handwriting pose already as a child? If not, how hard was it to teach yourself writing that way?


At work, we use the .editorconfig of the .NET runtime, with slight modifications:

https://github.com/dotnet/runtime/blob/main/.editorconfig


This appears to be the OP / Workleap's editor config. https://github.com/workleap/wl-dotnet-codingstandards/blob/m...


Hi, as someone also fiddling around with a concatenative toy language, I wanted to ask if any of your languages have a public repository somewhere? You seem very knowledgeable on the topic and your descriptions made me interested.


I second this request!


I like it! For me, I can confirm that the smaller the task, the less likely it is for me to procrastinate on it. I also didn't know that receipt printers don't need ink, that's cool. On a similar note: me and my partner recently also started using an app that divides up the household chores into small tasks and schedules them for us (e.g. "today you have to vacuum the living room"). For us, this prevents conflicts and also frees the mind of having to keep track of those things.


Thanks for your comment! I have the same question as hyperific — which app are you using?


https://sweepy.com/

There is also one that is called "tody" that we didn't try out. Both require a small subscription fee though, which I really dislike. I wish I had found a nice open source alternative. Besides the subscription fee (which was like 18€/year for us both), I have no complaints yet about the app.


Thanks for your answer!


What app are you using?


See my answer on the sibling comment.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: