Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance painless documentation #22720

Closed
gmoskovicz opened this issue Jan 20, 2017 · 18 comments
Closed

Enhance painless documentation #22720

gmoskovicz opened this issue Jan 20, 2017 · 18 comments
Assignees
Labels
:Core/Infra/Scripting Scripting abstractions, Painless, and Mustache >docs General docs changes

Comments

@gmoskovicz
Copy link
Contributor

We state that painless is similar than Groovy, but to be fair most of the code that you paste from groovy will need to be modified in order to work with this new language.

One simple example is the following that works in Groovy but not in Painless:

variable = list.sort { a, b -> a.value == b.value ? 0 : a.value < b.value ? -1 : 1 }

Now, this could be translated into the following:

variable = list.sort( (a, b) -> a.value == b.value ? 0 : a.value < b.value ? -1 : 1 );

Also, looks like joda.time.DateTime cannot be used, and there is no clear explanation how to deal with dates. See #22162.

As you can see, it's similar, but still you usually need to modify a big part of the code. Unfortunately this type of similarities are not documented, nor you can understand in an easy way how to translate groovy or how to develop with painless. My proposal is to:

  1. Clearly explain in the documentation that while it's similar to groovy, there are a lot of differences which means that you will need to translate most of your code into painless.
  2. Enhance the documentation with sections like "how to translate groovy to painless".
  3. Add more sample docs around painless.
  4. Add documentation on how the language works, what things we support, and what things we don't support.

We shouldn't expect to have a large documentation, but at least to have the general concepts. Just to see how other languages are explained:

@jasontedor
Copy link
Member

jasontedor commented Jan 20, 2017

We state that painless is similar than Groovy, but to be fair most of the code that you paste from groovy will need to be modified in order to work with this new language.

To be fair, when developers hear that two languages are similar, they do not have an expectation that they can paste code from one language into another. For example, developers freely admit that C# and Java are similar (in fact, very similar), but no developer comfortable with one of those languages expects they can paste code back and forth between the two (sometimes you can paste a snippet, the vast majority of the time you can not).

This does not negate the point that we should always work to improve our documentation, especially for a feature as nascent as Painless is, but I do think it's worth correcting the expectation that developers have when they say and hear that two languages are similar.

@jdconrad
Copy link
Contributor

Agree 100% the documentation needs improvements. I'm currently working on making some, but there's a lot to cover and it's going to take some time to get there. I also see how comparing this language to Groovy could be confusing given the lack of documentation here.

@nik9000
Copy link
Member

nik9000 commented Jan 20, 2017

I'm still working on prerequisites for an API reference.... I think I have one review left before I can revive my work on the reference. That'll help. Some.

@nik9000
Copy link
Member

nik9000 commented Jan 25, 2017

The API reference I was talking about: #22775

nik9000 added a commit that referenced this issue Jan 26, 2017
Adds "Appending B. Painless API Reference", a reference of all classes
and methods available from Painless. Removes links to java packages
because they contain methods that we don't expose and don't contain
methods that we do expose (the ones in Augmentation). Instead this
generates a list of every class and every exposed method using the same
type information available to the
interpreter/compiler/whatever-we-call-it. From there you can jump to
the relevant docs.

Right now you build all the asciidoc files by running
```
gradle generatePainlessApi
```

These files are expected to be committed because we build the docs
without running `gradle`.

Also changes the output of `Debug.explain` so that it is easy to
search for the class in the generated reference documentation.

You can also run it in an IDE safely if you pass the path to the
directory in which to generate the docs as the first parameter. It'll
blow away the entire directory an recreate it from scratch so be careful.

And then you can build the docs by running something like:
```
../docs/build_docs.pl --out ../built_docs/ --doc docs/reference/index.asciidoc --open
```

That is, if you have checked out https://github.com/elastic/docs in
`../docs`. Wait a minute or two and your browser will pop open in with
all of Elasticsearch's reference documentation. If you go to
`http://localhost:8000/painless-api-reference.html` you can see this
list. Or you can get there by following the links to `Modules` and
`Scripting` and `Painless` and then clicking the link in the paragraphs
below titled `Appendix B. Painless API Reference`.

I like having these in asciidoc because we can deep link to them from the
rest of the guide with constructs like
`<<painless-api-reference-Object-hashCode-0>>` and
`<<painless-api-reference->>` and we get link checking. Then the only
brittle link maintenance bit is the link generation for javadoc. Which
sucks. But I think it is important that we link to the methods directly
so they are easy to find.

Relates to #22720
nik9000 added a commit that referenced this issue Jan 26, 2017
Adds "Appending B. Painless API Reference", a reference of all classes
and methods available from Painless. Removes links to java packages
because they contain methods that we don't expose and don't contain
methods that we do expose (the ones in Augmentation). Instead this
generates a list of every class and every exposed method using the same
type information available to the
interpreter/compiler/whatever-we-call-it. From there you can jump to
the relevant docs.

Right now you build all the asciidoc files by running
```
gradle generatePainlessApi
```

These files are expected to be committed because we build the docs
without running `gradle`.

Also changes the output of `Debug.explain` so that it is easy to
search for the class in the generated reference documentation.

You can also run it in an IDE safely if you pass the path to the
directory in which to generate the docs as the first parameter. It'll
blow away the entire directory an recreate it from scratch so be careful.

And then you can build the docs by running something like:
```
../docs/build_docs.pl --out ../built_docs/ --doc docs/reference/index.asciidoc --open
```

That is, if you have checked out https://github.com/elastic/docs in
`../docs`. Wait a minute or two and your browser will pop open in with
all of Elasticsearch's reference documentation. If you go to
`http://localhost:8000/painless-api-reference.html` you can see this
list. Or you can get there by following the links to `Modules` and
`Scripting` and `Painless` and then clicking the link in the paragraphs
below titled `Appendix B. Painless API Reference`.

I like having these in asciidoc because we can deep link to them from the
rest of the guide with constructs like
`<<painless-api-reference-Object-hashCode-0>>` and
`<<painless-api-reference->>` and we get link checking. Then the only
brittle link maintenance bit is the link generation for javadoc. Which
sucks. But I think it is important that we link to the methods directly
so they are easy to find.

Relates to #22720
@PhaedrusTheGreek
Copy link
Contributor

PhaedrusTheGreek commented Jan 31, 2017

My findings from working with painless a bit:

  • You can't declare global scope variables in painless, like you can in groovy. If you need to share variables, pass them in functions. (not documented)
  • All functions must be declared at the top of the script (documented)
  • In compile errors, Character number is thrown, not Line number. In vim you can do :goto <character> (not documented, existing issue)
  • in .vimrc , add this for syntax highlighting: au BufRead,BufNewFile *.painless set filetype=groovy (helpful hints?)
  • You can't use groovy shorthand for loop iteration (list.each {}), you must use the Java style syntax: for (Object it : list) { } (documented)

Attached is an example that will traverse each JSON document in order to fix invalid fields names. Can be attached to an ingest pipeline:

@jdconrad
Copy link
Contributor

@PhaedrusTheGreek Thank you for the feedback here! Appreciate it.

@dakrone
Copy link
Member

dakrone commented Jan 31, 2017

I wouldn't want Emacs to be left out, so:

(add-to-list 'auto-mode-alist '("\\.painless$" . groovy-mode))

(requires groovy-mode to already be installed of course)

@rjernst
Copy link
Member

rjernst commented Jan 31, 2017

in .vimrc , add this for syntax highlighting: au BufRead,BufNewFile *.painless set filetype=groovy
I wouldn't want Emacs to be left out

I would not do this. If we want syntax highlighting, then we should create our own filetype plugins for vim/emacs. Otherwise you will think eg a closure is valid, because of syntax highlighting, but painless does not have closures. Likewise, it would not properly format lambdas, since groovy does not support them.

@nik9000
Copy link
Member

nik9000 commented Jan 31, 2017

You can't use groovy shorthand for loop iteration (list.each {}), you must use the Java style syntax: for (Object it : list) { } (documented)

I believe you can do it java style like list.stream.forEach(e -> {code}). Painless doesn't support groovy's funky rules around parameters.

@dakrone
Copy link
Member

dakrone commented Jan 31, 2017

we should create our own filetype plugins for vim/emacs

Sure, I'll add this to my TODO list

@jdconrad
Copy link
Contributor

@dakrone If/when you find the time to do this, maybe you can just pull from the existing grammar files to know what valid syntax is.

@nik9000
Copy link
Member

nik9000 commented Feb 7, 2017

maybe you can just pull from the existing grammar files to know what valid syntax is.

Don't forget the semicolon hacks!

nik9000 added a commit to nik9000/elasticsearch that referenced this issue Feb 7, 2017
Painless uses Ruby-like method dispatch (reciever type, method name,
and arity) rather than Java-like (reciever type, method name, and
argument compile time types) or Groovy-like method dispatch (receiver
type, method name, and argument run time types). We do this for
mostly good reasons but we never documented it.

Relates to elastic#22720
nik9000 added a commit that referenced this issue Feb 7, 2017
Painless uses Ruby-like method dispatch (reciever type, method name,
and arity) rather than Java-like (reciever type, method name, and
argument compile time types) or Groovy-like method dispatch (receiver
type, method name, and argument run time types). We do this for
mostly good reasons but we never documented it.

Relates to #22720
nik9000 added a commit that referenced this issue Feb 7, 2017
Painless uses Ruby-like method dispatch (reciever type, method name,
and arity) rather than Java-like (reciever type, method name, and
argument compile time types) or Groovy-like method dispatch (receiver
type, method name, and argument run time types). We do this for
mostly good reasons but we never documented it.

Relates to #22720
nik9000 added a commit that referenced this issue Feb 7, 2017
Painless uses Ruby-like method dispatch (reciever type, method name,
and arity) rather than Java-like (reciever type, method name, and
argument compile time types) or Groovy-like method dispatch (receiver
type, method name, and argument run time types). We do this for
mostly good reasons but we never documented it.

Relates to #22720
@Cinerar
Copy link

Cinerar commented Feb 10, 2017

@jdconrad Please find some time to answer StackOverFlow questions, right now it is very hard learning curve.

@jdconrad
Copy link
Contributor

@Cinerar I'd be happy to. Do you have any particular questions or links to questions that you would like to me to prioritize?

@gmoskovicz
Copy link
Contributor Author

@Cinerar it is more appropriate to open a new issue in http://discuss.elastic.co/ if you have a specific question. I am sure that @jdconrad or any other Engineer will be more than happy to help 😃 .

@Cinerar
Copy link

Cinerar commented Feb 10, 2017

@PhaedrusTheGreek
Copy link
Contributor

A few things

  • Semicolons are required, unlike groovy
  • In script file, as noted here, params are accessible via params.<your_var> instead of in the base scope.

@clintongormley clintongormley added the :Core/Infra/Scripting Scripting abstractions, Painless, and Mustache label Feb 14, 2018
@jdconrad
Copy link
Contributor

Closing this in favor of (#23777)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Core/Infra/Scripting Scripting abstractions, Painless, and Mustache >docs General docs changes
Projects
None yet
Development

No branches or pull requests

10 participants