Closed brlebtag closed 5 years ago
The main reason why the majority of Node.js operations are asynchronous (i.e. you need to specify a callback) is to prevent blocking the event loop and delegate I/O operations to other threads in order to gain additional speed by allowing other useful JavaScript operations to be executed in the main thread while other threads are waiting on the kernel or I/O requests. Browser is not a server and doesn't need to deal with a large amount of requests per seconds, so browser's prompt
is synchronous. Note that almost all Node.js operations have their synchronous counterpart.
In general, if something can be implemented in several lines of code, it probably doesn't belong to Node.js core. For instance, the method you're proposing doesn't require you to install external dependencies or to remember something complicated. It can be achieved in just a few lines of code:
const fs = require('fs');
const prompt = msg => {
fs.writeSync(1, String(msg));
let s = '', buf = Buffer.alloc(1);
while(buf[0] - 10 && buf[0] - 13)
s += buf, fs.readSync(0, buf, 0, 1, 0);
return s.slice(1);
};
You can paste the above function in your application, then use it like this:
const result = prompt('Input something: ');
console.log('Your input was: ' + result);
First of all, thank you for your reply. I don't know if I sounded a little bit rude saying the input functionality was broken but believe me that was not my intention at all.
I agree with you in some parts of your rationale but I don't agree with you completely. I don't know if I'll be able to convince you. But at least, I'll try it. So, sorry to bother you a little bit more.
1º - Node.js is a multipurpose language:
I totally know that the majority of Node.js operations are asynchronous. And by being that way it can, for example, server millions of users per second ( I don't know the exact number but you got the idea).
But I can also use node.js to create a simple terminal application. And, In a simple terminal application, I don't care serving millions of users per second. I just want to code as simple and fast as possible.
I prefer to use node.js to shell script. And maybe I'm too ignorant but I like to write my node.js code like I write code for shell script. but guess what? Node.js doesn't have a input function! Too bad!
2º - Some people know more than one language:
I'm a portuguese native speaker. I speak english and I'm trying to learn german now. Sometimes I don't remember things in english. Sometimes I mixed things with german. Sometimes I forget thing in my own native language.
Imagine now, computer programming languages!
I've already worked with C/C++, Java, Javascript, Node.js, C#, PHP, etc. I am not even going to start counting frameworks. I hope you got the point.
But there is more, I only wanted to solve my problem. I didn't want to remember that I can read from the input buffer (file descriptor 0) using readSync that is located in fs package. That I'll have to iterating over the buffer until I reach 10 (\n) or 13 (Carriage Return), etc...
3º - Imagine if I was using Node.js to teach computer programming.
You know, I'm master degree student. My dream is to become a teacher one day. Now, you imagine scene: I decided to use node.js in my class (because I love node.js, of course!). But my student know nothing John Snow about computer programming because is Programming 101!
What would be the first thing I'll teach them? Omg, of course. Hello World!
What about the next thing? Well, maybe a simple calculator. But wait! Node.js doesn't have a input function. How am I suppose to teach them about non-blocking function if they don't know what a function even means! or about file descriptor? I didn't teach them while yet!
never mind, I'll use Python!
Everything that I described was a bit allegorical but it helps to highlight my points.
I agree 3000% with Bruno.
Bruno has very wise words there. Must be from Brazil. Anyhow he's right. There should be a synchronous input you can switch on 'click' and yeah it's frozen solid to your simple CLI.
How can you TEACH someone what a blocking thread is if you don't allow them to block it thus?
That classroom analogy is absolutely perfect. Maybe the obvious comeback is something about the node REPL, but I'm with Bruno, you'd ideally want not to have to use a library helper function this actually should be in core. With Gnarly warnings on. Like a permanent deprecation to remind people to consider async for their million per second non blocking widget. For the kids.
On Sun, Jun 16, 2019, 11:14 AM Bruno G. A. Lebtag <notifications@github.com wrote:
First of all, thank you for your reply. I don't know if I sounded a little bit rude saying the input functionality was broken but believe me that was not my intention at all.
I agree with you in some parts of your rationale but I don't agree with you completely. I don't know if I'll be able to convince you. But at least, I'll try it. So, sorry to bother you a little bit more.
1º - Node.js is a multipurpose language:
I totally know that the majority of Node.js operations are asynchronous. And by being that way it can, for example, server millions of users per second ( I don't know the exact number but you got the idea).
But I can also use node.js to create a simple terminal application. And, In a simple terminal application, I don't care serving millions of users per second. I just want to code as simple and fast as possible.
I prefer to use node.js to shell script. And maybe I'm too ignorant but I like to write my node.js code like I write code for shell script. but guess what? Node.js doesn't have a input function! Too bad!
2º - Some people know more than one language:
I'm a portuguese native speaker. I speak english and I'm trying to learn german now. Sometimes I don't remember things in english. Sometimes I mixed things with german. Sometimes I forget thing in my own native language.
Imagine now, computer programming languages!
I've already worked with C/C++, Java, Javascript, Node.js, C#, PHP, etc. I am not even going to start counting frameworks. I hope you got the point.
But there is more, I only wanted to solve my problem. I didn't want to remember that I can read from the input buffer (file descriptor 0) using readSync that is located in fs package. That I'll have to iterating over the buffer until I reach 10 (\n) or 13 (Carriage Return), etc...
3º - Imagine if I was using Node.js to teach computer programming.
You know, I'm master degree student. My dream is to become a teacher one day. Now, you imagine scene: I decided to use node.js in my class (because I love node.js, of course!). But my student know nothing John Snow about computer programming because is Programming 101!
What would be the first thing I'll teach them? Omg, of course. Hello World!
What about the next thing? Well, maybe a simple calculator. But wait! Node.js doesn't have a input function. How am I suppose to teach them about non-blocking function if they don't know what a function even means! or about file descriptor? I didn't teach them while yet!
never mind, I'll use Python!
Everything that I described was a bit allegorical but it helps to highlight my points.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/nodejs/node/issues/28243?email_source=notifications&email_token=AAH2R43ZLTYKUFB3FHIA5YDP2VZTZA5CNFSM4HYO7EHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODXZBYDQ#issuecomment-502406158, or mute the thread https://github.com/notifications/unsubscribe-auth/AAH2R4YZPW436NCRZ4VZ4TLP2VZTZANCNFSM4HYO7EHA .
FWIW, there are userland modules that offer simple synchronous prompt()
-like commands. See, for example, https://www.npmjs.com/package/prompt-sync.
I'm tagging this feature request (despite the title) but I don't think this has much of a chance of getting accepted into Node.js core. This would go into the readline
module but that module is fully built around async I/O.
I think introducing something like this into the core could give programmers the wrong idea of how to use Node.js. Don't get me wrong - I think this is a great idea - but it would be best implemented (and it probably is already implemented) as a module. If I'm trying to learn a programming language that is heavily event-based (e.g. Node.js), it is going to make it harder for me to write "good" code when I start writing code that is not event-based by nature. It's not the Node.js way, and I think that would be confusing to those who are just learning the language and just grasping the event-based paradigm.
TL;DR: "Prompt functionality" would perhaps be a great help to prototyping things quickly, but it would also be bad for people who don't know how to use it properly.
I don't think prompt
is actually in conflict with async I/O if it's built on top of promises. It's certainly possible to provide something like
await readline.prompt('Please enter');
(node-core-utils actually had something like that implemented with just the readline module) and this can at least play with top-level await in the REPL and in ESM (top-level await in CommonJS, however, is unlikely to happen)
@joyeecheung OP says this though:
A.K.A without any callback hell or async/await
@dunnousername I think you're not seeing the point here.
I will never use prompt(), for example, in a web server. They belong to 2 different domain problems. You're not going to use it not even in a web server prototype(you'll send http requests instead). console.log is also not "event-based by nature" but no one complains about it.
I'd like to defend the reason why it should be prompt() only:
1- IO is the most fundamental functionality in any computer language:
A program that does not communicate with anything is a useless program. So you should have some sort of primitives in the language for that purpose.
python: print()/input() C: printf()/scanf() C++: cout/cin java: forget java, it is a horrible language... **puns intended hahaha
the list goes on...
2- You don't import console to use console.log:
why don't we import console to use console.log? because it's the most basic functionality ever...
prompt is the complement of console.log, so it should follow the same rule.
3- Javascript has prompt!:
Javascript has prompt in the first place! why was it removed? It makes no sense at all.
In my old days ( I am not that old, just kidding) we use it for everything. (good days, there wasn't so many javascript frameworks back then. Peaceful days indeed)
Javascript has prompt in the first place!
@brlebtag Not exactly. prompt()
is specified in the HTML spec and not in the ECMAScript (JavaScript) spec. This is kinda relevant. See below.
why was it removed? It makes no sense at all.
It wasn't removed, exactly. It's not part of V8. prompt()
( and setTimeout()
and a bunch of other things) are implemented partly or completely in the browser and not in V8. So, Node.js uses V8 as its JavaScript engine. But stuff that hangs off the window
global (which doesn't exist in V8--it's implemented in the browser) isn't implemented in V8 and ends up being things we have to implement ourselves (see setTimeout()
and friends), or stuff we just don't bother implementing because it makes no sense for Node.js (e.g., getComputedStyle()
). So prompt()
never got implemented. It wasn't actively removed.
That's not to say it can't or shouldn't be implemented. But the answer to your (possibly rhetorical) question there is that it wasn't removed and JavaScript doesn't exactly have it.
@Trott thanks man. I had no ideia. Good to know.
That's not to say it can't or shouldn't be implemented. But the answer to your (possibly rhetorical) question there is that it wasn't removed and JavaScript doesn't exactly have it.
haha I know, a bit overdramatic....
This feature request has been open for over a week now but no collaborators actually came out and spoke in favor of it. Ergo, thanks for the suggestion but I'm going to close it.
Node.js is a multipurpose programming language used everywhere and for everything.
But I always felt there was something broken about its terminal input functionality.
the easiest way to program is in a imperative manner (A.K.A without any callback hell or async/await).
it's very easy to print a value to the terminal, you just have to call console.log.
but why can't it be the same way for the input functionality? Why Do I have to google every single time for a way to get a input value from the terminal? Why do I have to import a module like
readline-sync
for a simple functionality that most programming languages have easily implemented. Why can't it be something like pythons's raw_input/input function?even in the browser, we have something like this:
Why can't we have the same thing for the terminal? It's easy to remember and I don't have import any external library.
I'm sorry if this was already discussed. But I was just trying to code something right now, and I just realise node.js's terminal input functionality is too hard to remember and it seems everyone is ok with that.
But I'm lazy. Programming languages should improve programmers' lives and not make their lives even harder.