Age | Commit message (Collapse) | Author |
|
This complements the `map_get/2` guard BIF introduced in #1784.
Rationale.
`map_get/2` allows accessing map fields in guards, but it might be
problematic in more complex guard expressions, for example:
foo(X) when map_get(a, X) =:= 1 or is_list(X) -> ...
The `is_list/1` part of the guard could never succeed since the
`map_get/2` guard would fail the whole guard expression. In this
situation, this could be solved by using `;` instead of `or` to separate
the guards, but it is not possible in every case.
To solve this situation, this PR proposes a `is_map_key/2` guard that
allows to check if a map has key inside a guard before trying to access
that key. When combined with `is_map/1` this allows to construct a
purely boolean guard expression testing a value of a key in a map.
Implementation.
Given the use case motivating the introduction of this function, the PR
contains compiler optimisations that produce optimial code for the
following guard expression:
foo(X) when is_map(X) and is_map_key(a, X) and map_get(a, X) =:= 1 -> ok;
foo(_) -> error.
Given all three tests share the failure label, the `is_map_key/2` and
`is_map/2` tests are optimised away.
As with `map_get/2` the `is_map_key/2` BIF is allowed in match specs.
|
|
Rationale
Today all compound data types except for maps can be deconstructed in guards.
For tuples we have `element/2` and for lists `hd/1` and `tl/1`. Maps are
completely opaque to guards. This means matching on maps can't be
abstracted into macros, which is often done with repetitive guards. It
also means that maps have to be always selected whole from ETS tables,
even when only one field would be enough, which creates a potential
efficiency issue.
This PR introduces an `erlang:map_get/2` guard-safe function that allows
extracting a map field in guard. An alternative to this function would be
to introduce the syntax for extracting a value from a map that was planned
in the original EEP: `Map#{Key}`.
Even outside of guards, since this function is a guard-BIF it is more
efficient than using `maps:get/2` (since it does not need to set up the
stack), and more convenient from pattern matching on the map (compare:
`#{key := Value} = Map, Value` to `map_get(key, Map)`).
Performance considerations
A common concern against adding this function is the notion that "guards
have to be fast" and ideally execute in constant time. While there are
some counterexamples (`length/1`), what is more important is the fact
that adding those functions does not change in any way the time
complexity of pattern matching - it's already possible to match on map
fields today directly in patterns - adding this ability to guards will
niether slow down or speed up the execution, it will only make certain
programs more convenient to write.
This first version is very naive and does not perform any optimizations.
|
|
|
|
Communication between Erlang processes has conceptually always been
performed through asynchronous signaling. The runtime system
implementation has however previously preformed most operation
synchronously. In a system with only one true thread of execution, this
is not problematic (often the opposite). In a system with multiple threads
of execution (as current runtime system implementation with SMP support)
it becomes problematic. This since it often involves locking of structures
when updating them which in turn cause resource contention. Utilizing
true asynchronous communication often avoids these resource contention
issues.
The case that triggered this change was contention on the link lock due
to frequent updates of the monitor trees during communication with a
frequently used server. The signal order delivery guarantees of the
language makes it hard to change the implementation of only some signals
to use true asynchronous signaling. Therefore the implementations
of (almost) all signals have been changed.
Currently the following signals have been implemented as true
asynchronous signals:
- Message signals
- Exit signals
- Monitor signals
- Demonitor signals
- Monitor triggered signals (DOWN, CHANGE, etc)
- Link signals
- Unlink signals
- Group leader signals
All of the above already defined as asynchronous signals in the
language. The implementation of messages signals was quite
asynchronous to begin with, but had quite strict delivery constraints
due to the ordering guarantees of signals between a pair of processes.
The previously used message queue partitioned into two halves has been
replaced by a more general signal queue partitioned into three parts
that service all kinds of signals. More details regarding the signal
queue can be found in comments in the erl_proc_sig_queue.h file.
The monitor and link implementations have also been completely replaced
in order to fit the new asynchronous signaling implementation as good
as possible. More details regarding the new monitor and link
implementations can be found in the erl_monitor_link.h file.
|
|
* maint:
Derive `erlang-shell-mode` properly from `comint-mode`
|
|
|
|
* maint:
emacs: delimiter first in icr works
emacs: Indent delimiter first in term elements correctly
emacs: Indent tuple (and maps) elements as list elements
Add emacs indention testcase
|
|
|
|
|
|
Avoid
From:
{
^^element1,
^^element2
}
To:
{
^element1,
^element2
}
|
|
|
|
|
|
|
|
|
|
|
|
* maint:
Update the version to 2.8.0
Remove the obsolete erlang-buffer-substring function
Add a :package-version property to the new defcustom erlang-shell-prompt-read-only
Bump the version number
Make the erlang-shell prompt read-only by default
Remove a mention of Emacs 21
Drop some redundant backwards compatibility code
Enable lexical binding for erlang-mode
Remove some ancient compatibility aliases
|
|
* upstream/pr/1474:
Update the version to 2.8.0
Remove the obsolete erlang-buffer-substring function
Add a :package-version property to the new defcustom erlang-shell-prompt-read-only
Bump the version number
Make the erlang-shell prompt read-only by default
Remove a mention of Emacs 21
Drop some redundant backwards compatibility code
Enable lexical binding for erlang-mode
Remove some ancient compatibility aliases
|
|
|
|
* maint:
Emacs: Update erlang-xref-find-definitions-module for Emacs 26
Emacs: Guess type of tag definition in Emacs 24
|
|
|
|
|
|
OTP-14520
|
|
The number of arguments to visit-tags-table-buffer have
increased in Emacs 26.
|
|
This concerns tag finding commands in Emacs 24. If the word at point
is preceded by a hash suggest as default a jump to a record
definition. If it is a question mark suggest a macro. Otherwise
assume it is a function. If it is not a qualified call assume it is a
local function.
|
|
OTP-14520
|
|
Conflicts:
erts/emulator/beam/bif.c
erts/emulator/beam/dist.c
erts/emulator/beam/dist.h
erts/emulator/beam/erl_bif_info.c
erts/emulator/beam/erl_node_tables.c
erts/emulator/beam/erl_node_tables.h
erts/emulator/beam/external.c
|
|
|
|
The default target is changed to be just the name at point when
xref-find-references is invoked. Previously the default was the same
as for xref-find-definitions. This included arity and other things
that do not make sense for xref-find-references.
|
|
|
|
|
|
|
|
erlang-shell-prompt-read-only
|
|
|
|
Allow for this behaviour to be customized via a defcustom.
|
|
|
|
|
|
|
|
|
|
Those were added 8 years ago and it's about time they were removed.
Now that we depend on a newer Emacs release, we can also drop the
function `erlang-obsolete`.
|
|
* dgud/emacs/update-bifs:
Update available bifs for 20
|
|
|
|
Fix loading of byte-compiled erlang.elc on Emacs 25
and the erlang shell.
|
|
Drop some legacy Emacs compatibility code
|
|
|
|
Follow the same pattern as pid_to_list
|
|
|
|
All of those are present on the target Emacs 24.1.
|
|
|
|
This commit removes some compatibility for old GNU Emacs releases
and XEmacs. erlang-mode didn't really work on them for a while now,
so this is just a cleanup, nothing actually changes.
It's part of the ongoing effort to clean up and modernize the codebase
of erlang-mode.
|
|
Only the xref front-end introduced in Emacs 25 consider arity. It is
not implemented for older emacsen.
Look for manual page files in lib/erlang/man in erlang-root-dir. Also
do not give up in erlang-man-module when not finding the manual page
file. Call manual-entry as a fallback.
Do not bother to populate menu-bar with man pages when menu-bar-mode
is nil.
Add erlang extensions also to dired-omit-extensions.
Remove some support for Emacs 18 and 19.
|