mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Merge branch 'main' into list-walk-with-index-until
This commit is contained in:
commit
a710dd18ac
25 changed files with 341 additions and 106 deletions
2
.github/workflows/nightly_linux_arm64.yml
vendored
2
.github/workflows/nightly_linux_arm64.yml
vendored
|
@ -25,7 +25,7 @@ jobs:
|
|||
run: ./ci/write_version.sh
|
||||
|
||||
- name: build release with lto
|
||||
run: cargo build --profile=release-with-lto --locked --bin roc
|
||||
run: cargo build --profile=release-with-lto --locked --bin roc --bin roc_ls
|
||||
|
||||
- name: get commit SHA
|
||||
run: echo "SHA=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_ENV
|
||||
|
|
2
.github/workflows/nightly_linux_x86_64.yml
vendored
2
.github/workflows/nightly_linux_x86_64.yml
vendored
|
@ -25,7 +25,7 @@ jobs:
|
|||
run: ./ci/write_version.sh
|
||||
|
||||
- name: build release with lto
|
||||
run: RUSTFLAGS="-C target-cpu=x86-64" cargo build --profile=release-with-lto --locked --bin roc
|
||||
run: RUSTFLAGS="-C target-cpu=x86-64" cargo build --profile=release-with-lto --locked --bin roc --bin roc_ls
|
||||
# target-cpu=x86-64 -> For maximal compatibility for all CPU's. This was also faster in our tests: https://roc.zulipchat.com/#narrow/stream/231635-compiler-development/topic/.2Ecargo.2Fconfig.2Etoml/near/325726299
|
||||
|
||||
- name: get commit SHA
|
||||
|
|
|
@ -42,11 +42,7 @@ jobs:
|
|||
run: ./ci/write_version.sh
|
||||
|
||||
- name: build nightly release
|
||||
run: cargo build --locked --profile=release-with-lto --bin roc
|
||||
|
||||
# this makes the roc binary a lot smaller
|
||||
- name: strip debug info
|
||||
run: strip ./target/release-with-lto/roc
|
||||
run: cargo build --locked --profile=release-with-lto --bin roc --bin roc_ls
|
||||
|
||||
- name: package release
|
||||
run: ./ci/package_release.sh ${{ env.RELEASE_FOLDER_NAME }}
|
||||
|
|
2
.github/workflows/nightly_macos_x86_64.yml
vendored
2
.github/workflows/nightly_macos_x86_64.yml
vendored
|
@ -32,7 +32,7 @@ jobs:
|
|||
# this issue may be caused by using older versions of XCode
|
||||
|
||||
- name: build release
|
||||
run: RUSTFLAGS="-C target-cpu=x86-64" cargo build --profile=release-with-lto --locked --bin roc
|
||||
run: RUSTFLAGS="-C target-cpu=x86-64" cargo build --profile=release-with-lto --locked --bin roc --bin roc_ls
|
||||
# target-cpu=x86-64 -> For maximal compatibility for all CPU's.
|
||||
|
||||
- name: get commit SHA
|
||||
|
|
|
@ -53,9 +53,7 @@ build-nightly-release:
|
|||
COPY --dir .git LICENSE LEGAL_DETAILS ci ./
|
||||
# version.txt is used by the CLI: roc --version
|
||||
RUN ./ci/write_version.sh
|
||||
RUN RUSTFLAGS=$RUSTFLAGS cargo build --profile=release-with-lto --locked --bin roc
|
||||
# strip debug info
|
||||
RUN strip ./target/release-with-lto/roc
|
||||
RUN RUSTFLAGS=$RUSTFLAGS cargo build --profile=release-with-lto --locked --bin roc --bin roc_ls
|
||||
RUN ./ci/package_release.sh $RELEASE_FOLDER_NAME
|
||||
RUN ls
|
||||
SAVE ARTIFACT ./$RELEASE_FOLDER_NAME.tar.gz AS LOCAL $RELEASE_FOLDER_NAME.tar.gz
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
- [**tutorial**](https://roc-lang.org/tutorial)
|
||||
- [**docs** for the standard library](https://www.roc-lang.org/builtins)
|
||||
- [**examples**](https://github.com/roc-lang/examples/tree/main/examples)
|
||||
- [**faq**: frequently asked questions](https://github.com/roc-lang/roc/blob/main/FAQ.md)
|
||||
- [**faq**: frequently asked questions](https://github.com/roc-lang/roc/blob/main/www/content/faq.md)
|
||||
- [**group chat**](https://roc.zulipchat.com) for help, questions and discussions
|
||||
|
||||
If you'd like to contribute, check out [good first issues](https://github.com/roc-lang/roc/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). Don't hesitate to ask for help on our [group chat](https://roc.zulipchat.com), we're friendly!
|
||||
|
|
|
@ -3,15 +3,21 @@
|
|||
# https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/
|
||||
set -euxo pipefail
|
||||
|
||||
cp target/release-with-lto/roc ./roc # to be able to delete "target" later
|
||||
# this makes the binaries a lot smaller
|
||||
strip ./target/release-with-lto/roc
|
||||
strip ./target/release-with-lto/roc_ls
|
||||
|
||||
# to be able to delete "target" later
|
||||
cp target/release-with-lto/roc ./roc
|
||||
cp target/release-with-lto/roc_ls ./roc_lang_server
|
||||
|
||||
# delete unnecessary files and folders
|
||||
git clean -fdx --exclude roc
|
||||
git clean -fdx --exclude roc --exclude roc_lang_server
|
||||
|
||||
mkdir $1
|
||||
|
||||
|
||||
mv roc LICENSE LEGAL_DETAILS $1
|
||||
mv roc roc_lang_server LICENSE LEGAL_DETAILS $1
|
||||
|
||||
mkdir $1/examples
|
||||
mv examples/helloWorld.roc examples/platform-switching examples/cli $1/examples
|
||||
|
|
|
@ -560,8 +560,6 @@ tau = 2 * pi
|
|||
# ------- Functions
|
||||
## Convert a number to a [Str].
|
||||
##
|
||||
## This is the same as calling `Num.format {}` - so for more details on
|
||||
## exact formatting, see `Num.format`.
|
||||
## ```
|
||||
## Num.toStr 42
|
||||
## ```
|
||||
|
@ -573,7 +571,6 @@ tau = 2 * pi
|
|||
## When this function is given a non-[finite](Num.isFinite)
|
||||
## [F64] or [F32] value, the returned string will be `"NaN"`, `"∞"`, or `"-∞"`.
|
||||
##
|
||||
## To get strings in hexadecimal, octal, or binary format, use `Num.format`.
|
||||
toStr : Num * -> Str
|
||||
intCast : Int a -> Int b
|
||||
|
||||
|
|
|
@ -30,12 +30,25 @@ pub fn call_bitcode_fn<'ctx>(
|
|||
args: &[BasicValueEnum<'ctx>],
|
||||
fn_name: &str,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
call_bitcode_fn_help(env, args, fn_name)
|
||||
let ret = call_bitcode_fn_help(env, args, fn_name)
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.unwrap_or_else(|| {
|
||||
panic!("LLVM error: Did not get return value from bitcode function {fn_name:?}")
|
||||
})
|
||||
});
|
||||
|
||||
if env.target_info.operating_system == roc_target::OperatingSystem::Windows {
|
||||
// On windows zig uses a vector type <2xi64> instead of a i128 value
|
||||
let vec_type = env.context.i64_type().vec_type(2);
|
||||
if ret.get_type() == vec_type.into() {
|
||||
return env
|
||||
.builder
|
||||
.build_bitcast(ret, env.context.i128_type(), "return_i128")
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn call_void_bitcode_fn<'ctx>(
|
||||
|
@ -54,7 +67,35 @@ fn call_bitcode_fn_help<'ctx>(
|
|||
args: &[BasicValueEnum<'ctx>],
|
||||
fn_name: &str,
|
||||
) -> CallSiteValue<'ctx> {
|
||||
let it = args.iter().map(|x| (*x).into());
|
||||
let it = args
|
||||
.iter()
|
||||
.map(|x| {
|
||||
if env.target_info.operating_system == roc_target::OperatingSystem::Windows {
|
||||
if x.get_type() == env.context.i128_type().into() {
|
||||
let parent = env
|
||||
.builder
|
||||
.get_insert_block()
|
||||
.and_then(|b| b.get_parent())
|
||||
.unwrap();
|
||||
|
||||
let alloca = create_entry_block_alloca(
|
||||
env,
|
||||
parent,
|
||||
x.get_type(),
|
||||
"pass_u128_by_reference",
|
||||
);
|
||||
|
||||
env.builder.build_store(alloca, *x).unwrap();
|
||||
|
||||
alloca.into()
|
||||
} else {
|
||||
*x
|
||||
}
|
||||
} else {
|
||||
*x
|
||||
}
|
||||
})
|
||||
.map(|x| (x).into());
|
||||
let arguments = bumpalo::collections::Vec::from_iter_in(it, env.arena);
|
||||
|
||||
let fn_val = env
|
||||
|
|
|
@ -1067,11 +1067,42 @@ pub fn module_from_builtins<'ctx>(
|
|||
|
||||
// Also, must_keep is the functions we depend on that would normally be provide by libc.
|
||||
// They are magically linked to by llvm builtins, so we must specify that they can't be DCE'd.
|
||||
let must_keep = ["_fltused", "floorf", "memcpy", "memset"];
|
||||
let must_keep = [
|
||||
"_fltused",
|
||||
"floorf",
|
||||
"memcpy",
|
||||
"memset",
|
||||
// I have no idea why this function is special.
|
||||
// Without it, some tests hang on M1 mac outside of nix.
|
||||
"__muloti4",
|
||||
// fixes `Undefined Symbol in relocation`
|
||||
"__udivti3",
|
||||
// Roc special functions
|
||||
"__roc_force_longjmp",
|
||||
"__roc_force_setjmp",
|
||||
"set_shared_buffer",
|
||||
];
|
||||
for func in module.get_functions() {
|
||||
let has_definition = func.count_basic_blocks() > 0;
|
||||
let name = func.get_name().to_string_lossy();
|
||||
if has_definition && !must_keep.contains(&name.as_ref()) {
|
||||
if has_definition
|
||||
&& !name.starts_with("roc_builtins.")
|
||||
&& !must_keep.contains(&name.as_ref())
|
||||
{
|
||||
func.set_linkage(Linkage::Private);
|
||||
}
|
||||
}
|
||||
|
||||
// Note, running DCE here is faster then waiting until full app DCE.
|
||||
let mpm = PassManager::create(());
|
||||
mpm.add_global_dce_pass();
|
||||
mpm.run_on(&module);
|
||||
|
||||
// Now that the unused compiler-rt functions have been removed,
|
||||
// mark that the builtin functions are allowed to be DCE'd if they aren't used.
|
||||
for func in module.get_functions() {
|
||||
let name = func.get_name().to_string_lossy();
|
||||
if name.starts_with("roc_builtins.") {
|
||||
func.set_linkage(Linkage::Private);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1100,13 +1100,22 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
NumBytesToU128 => {
|
||||
arguments!(list, position);
|
||||
|
||||
call_list_bitcode_fn(
|
||||
let ret = call_list_bitcode_fn(
|
||||
env,
|
||||
&[list.into_struct_value()],
|
||||
&[position],
|
||||
BitcodeReturns::Basic,
|
||||
bitcode::NUM_BYTES_TO_U128,
|
||||
)
|
||||
);
|
||||
|
||||
if env.target_info.operating_system == roc_target::OperatingSystem::Windows {
|
||||
// On windows the return type is not a i128, likely due to alignment
|
||||
env.builder
|
||||
.build_bitcast(ret, env.context.i128_type(), "empty_string")
|
||||
.unwrap()
|
||||
} else {
|
||||
ret
|
||||
}
|
||||
}
|
||||
NumCompare => {
|
||||
arguments_with_layouts!((lhs_arg, lhs_layout), (rhs_arg, rhs_layout));
|
||||
|
@ -2596,7 +2605,16 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
|||
}
|
||||
}
|
||||
PtrWidth::Bytes8 => {
|
||||
if target_int_width.stack_size() as usize > env.target_info.ptr_size() {
|
||||
let return_by_pointer = {
|
||||
if env.target_info.operating_system
|
||||
== roc_target::OperatingSystem::Windows
|
||||
{
|
||||
target_int_width.stack_size() as usize >= env.target_info.ptr_size()
|
||||
} else {
|
||||
target_int_width.stack_size() as usize > env.target_info.ptr_size()
|
||||
}
|
||||
};
|
||||
if return_by_pointer {
|
||||
let bitcode_return_type =
|
||||
zig_to_int_checked_result_type(env, target_int_width.type_name());
|
||||
|
||||
|
|
|
@ -684,6 +684,7 @@ impl MakeSpecializationsPass {
|
|||
struct State<'a> {
|
||||
pub root_id: ModuleId,
|
||||
pub root_subs: Option<Subs>,
|
||||
pub root_path: PathBuf,
|
||||
pub cache_dir: PathBuf,
|
||||
/// If the root is an app module, the shorthand specified in its header's `to` field
|
||||
pub opt_platform_shorthand: Option<&'a str>,
|
||||
|
@ -752,6 +753,7 @@ impl<'a> State<'a> {
|
|||
|
||||
fn new(
|
||||
root_id: ModuleId,
|
||||
root_path: PathBuf,
|
||||
opt_platform_shorthand: Option<&'a str>,
|
||||
target_info: TargetInfo,
|
||||
function_kind: FunctionKind,
|
||||
|
@ -770,6 +772,7 @@ impl<'a> State<'a> {
|
|||
|
||||
Self {
|
||||
root_id,
|
||||
root_path,
|
||||
root_subs: None,
|
||||
opt_platform_shorthand,
|
||||
cache_dir,
|
||||
|
@ -1077,8 +1080,9 @@ pub struct LoadStart<'a> {
|
|||
arc_modules: Arc<Mutex<PackageModuleIds<'a>>>,
|
||||
ident_ids_by_module: SharedIdentIdsByModule,
|
||||
root_id: ModuleId,
|
||||
opt_platform_shorthand: Option<&'a str>,
|
||||
root_path: PathBuf,
|
||||
root_msg: Msg<'a>,
|
||||
opt_platform_shorthand: Option<&'a str>,
|
||||
src_dir: PathBuf,
|
||||
}
|
||||
|
||||
|
@ -1101,7 +1105,7 @@ impl<'a> LoadStart<'a> {
|
|||
|
||||
let res_loaded = load_filename(
|
||||
arena,
|
||||
filename,
|
||||
filename.clone(),
|
||||
true,
|
||||
None,
|
||||
None,
|
||||
|
@ -1136,6 +1140,7 @@ impl<'a> LoadStart<'a> {
|
|||
ident_ids_by_module,
|
||||
src_dir,
|
||||
root_id: header_output.module_id,
|
||||
root_path: filename,
|
||||
root_msg: header_output.msg,
|
||||
opt_platform_shorthand: header_output.opt_platform_shorthand,
|
||||
})
|
||||
|
@ -1162,7 +1167,7 @@ impl<'a> LoadStart<'a> {
|
|||
|
||||
let header_output = load_from_str(
|
||||
arena,
|
||||
filename,
|
||||
filename.clone(),
|
||||
src,
|
||||
Arc::clone(&arc_modules),
|
||||
Arc::clone(&ident_ids_by_module),
|
||||
|
@ -1178,6 +1183,7 @@ impl<'a> LoadStart<'a> {
|
|||
src_dir,
|
||||
ident_ids_by_module,
|
||||
root_id,
|
||||
root_path: filename,
|
||||
root_msg,
|
||||
opt_platform_shorthand: opt_platform_id,
|
||||
})
|
||||
|
@ -1352,6 +1358,7 @@ pub fn load_single_threaded<'a>(
|
|||
arc_modules,
|
||||
ident_ids_by_module,
|
||||
root_id,
|
||||
root_path,
|
||||
root_msg,
|
||||
src_dir,
|
||||
opt_platform_shorthand,
|
||||
|
@ -1367,6 +1374,7 @@ pub fn load_single_threaded<'a>(
|
|||
let number_of_workers = 1;
|
||||
let mut state = State::new(
|
||||
root_id,
|
||||
root_path,
|
||||
opt_platform_shorthand,
|
||||
target_info,
|
||||
function_kind,
|
||||
|
@ -1503,7 +1511,7 @@ fn state_thread_step<'a>(
|
|||
Ok(ControlFlow::Break(LoadResult::Monomorphized(monomorphized)))
|
||||
}
|
||||
Msg::FailedToReadFile { filename, error } => {
|
||||
let buf = to_file_problem_report_string(&filename, error);
|
||||
let buf = to_file_problem_report_string(filename, error);
|
||||
Err(LoadingProblem::FormattedReport(buf))
|
||||
}
|
||||
|
||||
|
@ -1654,7 +1662,7 @@ pub fn report_loading_problem(
|
|||
}
|
||||
LoadingProblem::FormattedReport(report) => report,
|
||||
LoadingProblem::FileProblem { filename, error } => {
|
||||
to_file_problem_report_string(&filename, error)
|
||||
to_file_problem_report_string(filename, error)
|
||||
}
|
||||
err => todo!("Loading error: {:?}", err),
|
||||
}
|
||||
|
@ -1677,6 +1685,7 @@ fn load_multi_threaded<'a>(
|
|||
arc_modules,
|
||||
ident_ids_by_module,
|
||||
root_id,
|
||||
root_path,
|
||||
root_msg,
|
||||
src_dir,
|
||||
opt_platform_shorthand,
|
||||
|
@ -1707,6 +1716,7 @@ fn load_multi_threaded<'a>(
|
|||
|
||||
let mut state = State::new(
|
||||
root_id,
|
||||
root_path,
|
||||
opt_platform_shorthand,
|
||||
target_info,
|
||||
function_kind,
|
||||
|
@ -2238,6 +2248,7 @@ fn update<'a>(
|
|||
let buf = to_https_problem_report_string(
|
||||
url,
|
||||
Problem::InvalidUrl(url_err),
|
||||
header.module_path,
|
||||
);
|
||||
return Err(LoadingProblem::FormattedReport(buf));
|
||||
}
|
||||
|
@ -3159,7 +3170,7 @@ fn finish_specialization<'a>(
|
|||
}
|
||||
Valid(To::NewPackage(p_or_p)) => PathBuf::from(p_or_p.as_str()),
|
||||
other => {
|
||||
let buf = to_missing_platform_report(state.root_id, other);
|
||||
let buf = report_cannot_run(state.root_id, state.root_path, other);
|
||||
return Err(LoadingProblem::FormattedReport(buf));
|
||||
}
|
||||
};
|
||||
|
@ -3513,9 +3524,7 @@ fn load_builtin_module_help<'a>(
|
|||
) -> (HeaderInfo<'a>, roc_parse::state::State<'a>) {
|
||||
let is_root_module = false;
|
||||
let opt_shorthand = None;
|
||||
|
||||
let filename = PathBuf::from(filename);
|
||||
|
||||
let parse_state = roc_parse::state::State::new(src_bytes.as_bytes());
|
||||
let parsed = roc_parse::module::parse_header(arena, parse_state.clone());
|
||||
|
||||
|
@ -3968,6 +3977,7 @@ fn parse_header<'a>(
|
|||
module_timing,
|
||||
)?;
|
||||
|
||||
let filename = resolved_header.module_path.clone();
|
||||
let mut messages = Vec::with_capacity(packages.len() + 1);
|
||||
|
||||
// It's important that the app header is first in the list!
|
||||
|
@ -3982,6 +3992,7 @@ fn parse_header<'a>(
|
|||
module_id,
|
||||
module_ids,
|
||||
ident_ids_by_module,
|
||||
filename,
|
||||
);
|
||||
|
||||
// Look at the app module's `to` keyword to determine which package was the platform.
|
||||
|
@ -4084,6 +4095,7 @@ fn load_packages<'a>(
|
|||
module_id: ModuleId,
|
||||
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
|
||||
ident_ids_by_module: SharedIdentIdsByModule,
|
||||
filename: PathBuf,
|
||||
) {
|
||||
// Load all the packages
|
||||
for Loc { value: entry, .. } in packages.iter() {
|
||||
|
@ -4121,7 +4133,7 @@ fn load_packages<'a>(
|
|||
}
|
||||
}
|
||||
Err(problem) => {
|
||||
let buf = to_https_problem_report_string(src, problem);
|
||||
let buf = to_https_problem_report_string(src, problem, filename);
|
||||
|
||||
load_messages.push(Msg::FailedToLoad(LoadingProblem::FormattedReport(buf)));
|
||||
return;
|
||||
|
@ -6581,7 +6593,11 @@ fn to_parse_problem_report<'a>(
|
|||
buf
|
||||
}
|
||||
|
||||
fn to_missing_platform_report(module_id: ModuleId, other: &PlatformPath) -> String {
|
||||
fn report_cannot_run(
|
||||
module_id: ModuleId,
|
||||
filename: PathBuf,
|
||||
platform_path: &PlatformPath,
|
||||
) -> String {
|
||||
use roc_reporting::report::{Report, RocDocAllocator, DEFAULT_PALETTE};
|
||||
use ven_pretty::DocAllocator;
|
||||
use PlatformPath::*;
|
||||
|
@ -6591,20 +6607,20 @@ fn to_missing_platform_report(module_id: ModuleId, other: &PlatformPath) -> Stri
|
|||
let alloc = RocDocAllocator::new(&[], module_id, &interns);
|
||||
|
||||
let report = {
|
||||
match other {
|
||||
match platform_path {
|
||||
Valid(_) => unreachable!(),
|
||||
NotSpecified => {
|
||||
let doc = alloc.stack([
|
||||
alloc.reflow("I could not find a platform based on your input file."),
|
||||
alloc.reflow(r"Does the module header contain an entry that looks like this:"),
|
||||
alloc.reflow(r"Does the module header have an entry that looks like this?"),
|
||||
alloc
|
||||
.parser_suggestion(" packages { pf: \"platform\" }")
|
||||
.parser_suggestion("packages { blah: \"…path or URL to platform…\" }")
|
||||
.indent(4),
|
||||
alloc.reflow("See also TODO."),
|
||||
alloc.reflow("Tip: The following part of the tutorial has an example of specifying a platform:\n\n<https://www.roc-lang.org/tutorial#building-an-application>"),
|
||||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "NO PLATFORM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
|
@ -6619,7 +6635,7 @@ fn to_missing_platform_report(module_id: ModuleId, other: &PlatformPath) -> Stri
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "NO PLATFORM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
|
@ -6634,7 +6650,7 @@ fn to_missing_platform_report(module_id: ModuleId, other: &PlatformPath) -> Stri
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "NO PLATFORM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
|
@ -6649,7 +6665,7 @@ fn to_missing_platform_report(module_id: ModuleId, other: &PlatformPath) -> Stri
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "NO PLATFORM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
|
|
|
@ -234,7 +234,19 @@ fn verify_procedures<'a>(
|
|||
|
||||
if !has_changes.stdout.is_empty() {
|
||||
println!("{}", std::str::from_utf8(&has_changes.stdout).unwrap());
|
||||
panic!("Output changed: resolve conflicts and `git add` the file.");
|
||||
panic!(indoc!(
|
||||
r#"
|
||||
|
||||
Mono output has changed! This is normal when making changes to the builtins.
|
||||
To fix it; run these commands locally:
|
||||
|
||||
cargo test -p test_mono -p uitest --no-fail-fast
|
||||
git add -u
|
||||
git commit -S -m "update mono tests"
|
||||
git push origin YOUR_BRANCH_NAME
|
||||
|
||||
"#
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1090,7 +1090,7 @@ pub fn can_problem<'b>(
|
|||
title = "OVERAPPLIED CRASH".to_string();
|
||||
}
|
||||
Problem::FileProblem { filename, error } => {
|
||||
let report = to_file_problem_report(alloc, &filename, error);
|
||||
let report = to_file_problem_report(alloc, filename, error);
|
||||
doc = report.doc;
|
||||
title = report.title;
|
||||
}
|
||||
|
|
|
@ -1101,7 +1101,11 @@ where
|
|||
}
|
||||
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
pub fn to_https_problem_report_string(url: &str, https_problem: Problem) -> String {
|
||||
pub fn to_https_problem_report_string(
|
||||
url: &str,
|
||||
https_problem: Problem,
|
||||
filename: PathBuf,
|
||||
) -> String {
|
||||
let src_lines: Vec<&str> = Vec::new();
|
||||
|
||||
let mut module_ids = ModuleIds::default();
|
||||
|
@ -1115,7 +1119,7 @@ pub fn to_https_problem_report_string(url: &str, https_problem: Problem) -> Stri
|
|||
|
||||
let mut buf = String::new();
|
||||
let palette = DEFAULT_PALETTE;
|
||||
let report = to_https_problem_report(&alloc, url, https_problem);
|
||||
let report = to_https_problem_report(&alloc, url, https_problem, filename);
|
||||
report.render_color_terminal(&mut buf, &alloc, &palette);
|
||||
|
||||
buf
|
||||
|
@ -1126,6 +1130,7 @@ pub fn to_https_problem_report<'b>(
|
|||
alloc: &'b RocDocAllocator<'b>,
|
||||
url: &'b str,
|
||||
https_problem: Problem,
|
||||
filename: PathBuf,
|
||||
) -> Report<'b> {
|
||||
match https_problem {
|
||||
Problem::UnsupportedEncoding(not_supported_encoding) => {
|
||||
|
@ -1154,7 +1159,7 @@ pub fn to_https_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "UNSUPPORTED ENCODING".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1189,7 +1194,7 @@ pub fn to_https_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "MULTIPLE ENCODINGS".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1224,7 +1229,7 @@ pub fn to_https_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "INVALID CONTENT HASH".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1241,7 +1246,7 @@ pub fn to_https_problem_report<'b>(
|
|||
alloc.concat([alloc.tip(), alloc.reflow(r"Is the URL correct?")]),
|
||||
]);
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "NOTFOUND".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1268,7 +1273,7 @@ pub fn to_https_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "IO ERROR".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1295,7 +1300,7 @@ pub fn to_https_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "IO ERROR".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1324,7 +1329,7 @@ pub fn to_https_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "HTTP ERROR".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1365,7 +1370,7 @@ pub fn to_https_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "INVALID EXTENSION SUFFIX".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1398,7 +1403,7 @@ pub fn to_https_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "INVALID EXTENSION".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1436,7 +1441,7 @@ pub fn to_https_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "INVALID FRAGMENT".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1474,7 +1479,7 @@ pub fn to_https_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "MISSING PACKAGE HASH".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1500,7 +1505,7 @@ pub fn to_https_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "HTTPS MANDATORY".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1543,7 +1548,7 @@ pub fn to_https_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "MISLEADING CHARACTERS".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1573,7 +1578,7 @@ pub fn to_https_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "FILE TOO LARGE".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1582,13 +1587,10 @@ pub fn to_https_problem_report<'b>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn to_file_problem_report_string(filename: &Path, error: io::ErrorKind) -> String {
|
||||
pub fn to_file_problem_report_string(filename: PathBuf, error: io::ErrorKind) -> String {
|
||||
let src_lines: Vec<&str> = Vec::new();
|
||||
|
||||
let mut module_ids = ModuleIds::default();
|
||||
|
||||
let module_id = module_ids.get_or_insert(&"find module name somehow?".into());
|
||||
|
||||
let interns = Interns::default();
|
||||
|
||||
// Report parsing and canonicalization problems
|
||||
|
@ -1604,16 +1606,16 @@ pub fn to_file_problem_report_string(filename: &Path, error: io::ErrorKind) -> S
|
|||
|
||||
pub fn to_file_problem_report<'b>(
|
||||
alloc: &'b RocDocAllocator<'b>,
|
||||
filename: &Path,
|
||||
filename: PathBuf,
|
||||
error: io::ErrorKind,
|
||||
) -> Report<'b> {
|
||||
let filename: String = filename.to_str().unwrap().to_string();
|
||||
let filename_str: String = filename.to_str().unwrap().to_string();
|
||||
match error {
|
||||
io::ErrorKind::NotFound => {
|
||||
let doc = alloc.stack([
|
||||
alloc.reflow(r"I am looking for this file, but it's not there:"),
|
||||
alloc
|
||||
.string(filename)
|
||||
.string(filename_str)
|
||||
.annotate(Annotation::ParserSuggestion)
|
||||
.indent(4),
|
||||
alloc.concat([
|
||||
|
@ -1623,7 +1625,7 @@ pub fn to_file_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "FILE NOT FOUND".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1633,7 +1635,7 @@ pub fn to_file_problem_report<'b>(
|
|||
let doc = alloc.stack([
|
||||
alloc.reflow(r"I don't have the required permissions to read this file:"),
|
||||
alloc
|
||||
.string(filename)
|
||||
.string(filename_str)
|
||||
.annotate(Annotation::ParserSuggestion)
|
||||
.indent(4),
|
||||
alloc
|
||||
|
@ -1641,7 +1643,7 @@ pub fn to_file_problem_report<'b>(
|
|||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "FILE PERMISSION DENIED".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
@ -1652,13 +1654,16 @@ pub fn to_file_problem_report<'b>(
|
|||
let formatted = format!("{error}");
|
||||
let doc = alloc.stack([
|
||||
alloc.reflow(r"I tried to read this file:"),
|
||||
alloc.string(filename).annotate(Annotation::Error).indent(4),
|
||||
alloc
|
||||
.string(filename_str)
|
||||
.annotate(Annotation::Error)
|
||||
.indent(4),
|
||||
alloc.reflow(r"But ran into:"),
|
||||
alloc.text(formatted).annotate(Annotation::Error).indent(4),
|
||||
]);
|
||||
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
filename,
|
||||
doc,
|
||||
title: "FILE PROBLEM".to_string(),
|
||||
severity: Severity::Fatal,
|
||||
|
|
16
flake.nix
16
flake.nix
|
@ -27,8 +27,13 @@
|
|||
};
|
||||
|
||||
outputs = { self, nixpkgs, rust-overlay, flake-utils, nixgl, ... }@inputs:
|
||||
let supportedSystems = [ "x86_64-linux" "x86_64-darwin" "aarch64-darwin" "aarch64-linux" ];
|
||||
in flake-utils.lib.eachSystem supportedSystems (system:
|
||||
let
|
||||
supportedSystems = [ "x86_64-linux" "x86_64-darwin" "aarch64-darwin" "aarch64-linux" ];
|
||||
|
||||
templates = import ./nix/templates { };
|
||||
in
|
||||
{ inherit templates; } //
|
||||
flake-utils.lib.eachSystem supportedSystems (system:
|
||||
let
|
||||
overlays = [ (import rust-overlay) ]
|
||||
++ (if system == "x86_64-linux" then [ nixgl.overlay ] else [ ]);
|
||||
|
@ -143,5 +148,12 @@
|
|||
cli = rocBuild.roc-cli;
|
||||
lang-server = rocBuild.roc-lang-server;
|
||||
};
|
||||
|
||||
apps = {
|
||||
default = {
|
||||
type = "app";
|
||||
program = "${rocBuild.roc-cli}/bin/roc";
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,11 +6,12 @@ play around with as long as you have a tolerance for missing features and compil
|
|||
|
||||
The [tutorial](https://roc-lang.org/tutorial) is the best place to learn about how to use the language - it assumes no prior knowledge of Roc or similar languages. (If you already know [Elm](https://elm-lang.org/), then [Roc for Elm Programmers](https://github.com/roc-lang/roc/blob/main/roc-for-elm-programmers.md) may be of interest.)
|
||||
|
||||
If you have a specific question, the [FAQ](../FAQ.md) might have an answer, although [Roc Zulip chat](https://roc.zulipchat.com) is overall the best place to ask questions and get help! It's also where we discuss [ideas](https://roc.zulipchat.com/#narrow/stream/304641-ideas) for the language. If you want to get involved in contributing to the language, Zulip is also a great place to ask about good first projects.
|
||||
If you have a specific question, the [FAQ](../www/content/faq.md) might have an answer, although [Roc Zulip chat](https://roc.zulipchat.com) is overall the best place to ask questions and get help! It's also where we discuss [ideas](https://roc.zulipchat.com/#narrow/stream/304641-ideas) for the language. If you want to get involved in contributing to the language, Zulip is also a great place to ask about good first projects.
|
||||
|
||||
## Installation
|
||||
|
||||
- [🐧 Linux x86_64](linux_x86_64.md)
|
||||
- [❄️ Nix Linux/MacOS](nix.md)
|
||||
- [🍏 MacOS Apple Silicon](macos_apple_silicon.md)
|
||||
- [🍏 MacOS x86_64](macos_x86_64.md)
|
||||
- [🟦 Windows](windows.md)
|
||||
|
|
48
getting_started/nix.md
Normal file
48
getting_started/nix.md
Normal file
|
@ -0,0 +1,48 @@
|
|||
## Try out
|
||||
|
||||
To quickly try out roc without installing, use `nix run`:
|
||||
```shell
|
||||
nix run roc-lang/roc -- <roc args>
|
||||
# examples:
|
||||
# - nix run roc-lang/roc -- repl
|
||||
# - nix run roc-lang/roc -- dev main.roc
|
||||
```
|
||||
|
||||
## Use with Flakes
|
||||
|
||||
|
||||
### Start your project with our template
|
||||
|
||||
```shell
|
||||
# use the template in the current directory
|
||||
nix flake init --template github:roc-lang/roc#simple --refresh
|
||||
```
|
||||
|
||||
### Add roc to existing flake
|
||||
```nix
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
roc.url = "github:roc-lang/roc";
|
||||
};
|
||||
|
||||
outputs = {nixpkgs, roc, flake-utils, ...}:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
rocPkgs = roc.packages.${system};
|
||||
in
|
||||
{
|
||||
devShells = {
|
||||
default = pkgs.mkShell {
|
||||
buildInputs = with pkgs;
|
||||
[
|
||||
rocPkgs.cli
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
```
|
|
@ -3,6 +3,8 @@ let
|
|||
inherit (compile-deps) zigPkg llvmPkgs llvmVersion llvmMajorMinorStr glibcPath libGccSPath;
|
||||
|
||||
subPackagePath = if subPackage != null then "crates/${subPackage}" else null;
|
||||
|
||||
mainBin = if subPackage == "lang_srv" then "roc_ls" else "roc";
|
||||
in
|
||||
rustPlatform.buildRustPackage {
|
||||
pname = "roc" + lib.optionalString (subPackage != null) "_${subPackage}";
|
||||
|
@ -84,4 +86,11 @@ rustPlatform.buildRustPackage {
|
|||
${wrapRoc}
|
||||
fi
|
||||
'';
|
||||
|
||||
# https://ryantm.github.io/nixpkgs/stdenv/meta/
|
||||
meta = {
|
||||
homepage = "https://www.roc-lang.org/";
|
||||
license = lib.licenses.upl;
|
||||
mainProgram = mainBin;
|
||||
};
|
||||
}
|
||||
|
|
7
nix/templates/default.nix
Normal file
7
nix/templates/default.nix
Normal file
|
@ -0,0 +1,7 @@
|
|||
{ ... }: rec {
|
||||
default = simple;
|
||||
simple = {
|
||||
description = "Basic flake with roc cli + lsp";
|
||||
path = ./simple;
|
||||
};
|
||||
}
|
38
nix/templates/simple/flake.nix
Normal file
38
nix/templates/simple/flake.nix
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
description = "Roc flake template";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
roc.url = "github:roc-lang/roc";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, roc, ... }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
|
||||
# see "packages =" in https://github.com/roc-lang/roc/blob/main/flake.nix
|
||||
rocPkgs = roc.packages.${system};
|
||||
|
||||
rocFull = rocPkgs.full;
|
||||
|
||||
in
|
||||
{
|
||||
formatter = pkgs.nixpkgs-fmt;
|
||||
|
||||
devShells = {
|
||||
default = pkgs.mkShell {
|
||||
buildInputs = with pkgs;
|
||||
[
|
||||
rocFull # includes CLI
|
||||
];
|
||||
|
||||
# For vscode plugin https://github.com/ivan-demchenko/roc-vscode-unofficial
|
||||
shellHook = ''
|
||||
export ROC_LSP_PATH=${rocFull}/bin/roc_ls
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
# Documentation
|
||||
|
||||
- [builtins](/builtins) - docs for modules built into the language—`Str`, `Num`, etc.
|
||||
|
@ -10,7 +9,7 @@ In the future, a language reference will be on this page too.
|
|||
|
||||
## [Guides](#guides) {#guides}
|
||||
|
||||
- [Frequently Asked Questions](https://github.com/roc-lang/roc/blob/main/FAQ.md)
|
||||
- [Frequently Asked Questions](https://www.roc-lang.org/faq.html)
|
||||
- [Roc for Elm Programmers](https://github.com/roc-lang/roc/blob/main/roc-for-elm-programmers.md)
|
||||
- [Tutorial](/tutorial)
|
||||
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
Click the ☰ button in the top left to see and search the table of contents.
|
||||
|
||||
# Frequently Asked Questions
|
||||
|
||||
## Where did the name Roc come from?
|
||||
|
||||
<img width="128" alt="The Roc logo, an origami bird" src="https://user-images.githubusercontent.com/1094080/92188927-e61ebd00-ee2b-11ea-97ef-2fc88e0094b0.png">
|
||||
|
||||
The Roc programming language is named after [a mythical bird](<https://en.wikipedia.org/wiki/Roc_(mythology)>).
|
||||
|
||||
That’s why the logo is a bird. It’s specifically an [_origami_ bird](https://youtu.be/9gni1t1k1uY) as an homage
|
||||
<svg viewBox="0 0 52 53" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Make this icon look nicer in dark mode. (Only Firefox supports this; others ignore it.) -->
|
||||
<style>@media (prefers-color-scheme: dark){polygon{fill:#9c7bea}}</style>
|
||||
<polygon fill="#7d59dd" points="0,0 23.8834,3.21052 37.2438,19.0101 45.9665,16.6324 50.5,22 45,22 44.0315,26.3689 26.4673,39.3424 27.4527,45.2132 17.655,53 23.6751,22.7086"/>
|
||||
</svg>
|
||||
|
||||
That's why the logo is a bird. It’s specifically an [_origami_ bird](https://youtu.be/9gni1t1k1uY) as an homage
|
||||
to [Elm](https://elm-lang.org/)’s tangram logo.
|
||||
|
||||
Roc is a direct descendant of Elm. The languages are similar, but not the same.
|
||||
|
@ -55,8 +57,10 @@ Both of these would make revising code riskier across the entire language, which
|
|||
Another option would be to define that function equality always returns `false`. So both of these would evaluate
|
||||
to `false`:
|
||||
|
||||
- `(\x -> x + 1) == (\x -> 1 + x)`
|
||||
- `(\x -> x + 1) == (\x -> x + 1)`
|
||||
```roc
|
||||
(\x -> x + 1) == (\x -> 1 + x) #false
|
||||
(\x -> x + 1) == (\x -> x + 1) #false
|
||||
```
|
||||
|
||||
This makes function equality effectively useless, while still technically allowing it. It has some other downsides:
|
||||
|
||||
|
@ -252,11 +256,11 @@ the downsides.
|
|||
|
||||
In Roc, both of these expressions evaluate to `"Hello, World!"`
|
||||
|
||||
```elixir
|
||||
```roc
|
||||
Str.concat "Hello, " "World!"
|
||||
```
|
||||
|
||||
```elixir
|
||||
```roc
|
||||
"Hello, "
|
||||
|> Str.concat "World!"
|
||||
```
|
||||
|
@ -273,12 +277,12 @@ In Roc, both expressions evaluate to the same thing because Roc's `|>` operator
|
|||
|
||||
This comes up in other situations besides string concatenation. For example, consider subtraction and division:
|
||||
|
||||
```elixir
|
||||
```roc
|
||||
someNumber
|
||||
|> Num.div 2
|
||||
```
|
||||
|
||||
```elixir
|
||||
```roc
|
||||
someNumber
|
||||
|> Num.sub 1
|
||||
```
|
||||
|
@ -292,7 +296,7 @@ experienced users.
|
|||
|
||||
The way `|>` works in Roc has a second benefit when it comes to higher-order functions. Consider these two examples:
|
||||
|
||||
```elixir
|
||||
```roc
|
||||
answer = List.map numbers \num ->
|
||||
someFunction
|
||||
"some argument"
|
||||
|
@ -300,7 +304,7 @@ answer = List.map numbers \num ->
|
|||
anotherArg
|
||||
```
|
||||
|
||||
```elixir
|
||||
```roc
|
||||
numbers
|
||||
|> List.map Num.abs
|
||||
```
|
||||
|
@ -311,7 +315,7 @@ In a curried language, these two examples couldn't both be valid. In order for `
|
|||
|
||||
This means the first example would have to change from this...
|
||||
|
||||
```elixir
|
||||
```roc
|
||||
answer = List.map numbers \num ->
|
||||
someFunction
|
||||
"some argument"
|
||||
|
@ -321,7 +325,7 @@ answer = List.map numbers \num ->
|
|||
|
||||
...to this:
|
||||
|
||||
```elixir
|
||||
```roc
|
||||
answer =
|
||||
List.map
|
||||
(\num ->
|
||||
|
@ -370,7 +374,7 @@ And however easy Roc would be to learn if it had currying, the language is certa
|
|||
a new function by composing together two existing functions without naming intermediate arguments.
|
||||
Here's an example:
|
||||
|
||||
```elm
|
||||
```roc
|
||||
reverseSort : List elem -> List elem
|
||||
reverseSort = compose List.reverse List.sort
|
||||
|
||||
|
@ -380,7 +384,7 @@ compose = \f, g, x -> f (g x)
|
|||
|
||||
Here's a way to write it without pointfree function composition:
|
||||
|
||||
```elm
|
||||
```roc
|
||||
reverseSort : List elem -> List elem
|
||||
reverseSort = \list -> List.reverse (List.sort list)
|
||||
```
|
||||
|
@ -443,7 +447,3 @@ There were a few reasons for this rewrite.
|
|||
4. Zig has more tools for working in a memory-unsafe environment, such as reporting memory leaks in tests. These have been helpful in finding bugs that are out of scope for safe Rust.
|
||||
|
||||
The split of Rust for the compiler and Zig for the standard library has worked well so far, and there are no plans to change it.
|
||||
|
||||
## Why is the website so basic?
|
||||
|
||||
We have a very basic website on purpose, it helps set expectations that roc is a work in progress and not ready yet for a first release.
|
|
@ -5,7 +5,7 @@ Roc is a very young language with many incomplete features and known bugs. It do
|
|||
There are currently a few known OS-specific issues:
|
||||
* **macOS:** There are no known compatibility issues, but the compiler doesn't run as fast as it does on Linux or Windows, because we don't (yet) do our own linking like we do on those targets. (Linking works similarly on Linux and Windows, but the way macOS does it is both different and significantly more complicated.)
|
||||
* **Windows:** There are some known Windows-specific compiler bugs, and probably some other unknown ones because more people have tried out Roc on Mac and Linux than on Windows.
|
||||
* **Linux:** The nightlies are built with glibc, so they aren't usable on distros that don't use (dynamically linked) glibc, like Alpine or NixOS. In the future we plan to build Linux releases with [musl libc](https://wiki.musl-libc.org/) to address this, but this requires [building LLVM from source with musl](https://wiki.musl-libc.org/building-llvm.html).
|
||||
* **Linux:** The nightlies are built with glibc, so they aren't usable on distros that don't use glibc, like Alpine. In the future we plan to build Linux releases with [musl libc](https://wiki.musl-libc.org/) to address this, but this requires [building LLVM from source with musl](https://wiki.musl-libc.org/building-llvm.html).
|
||||
* **Other operating systems:** Roc has not been built on any other operating systems. [Building from source](https://github.com/roc-lang/roc/blob/main/BUILDING_FROM_SOURCE.md) on another OS might work, but you might very well be the first person ever to try it!
|
||||
|
||||
### [Getting Started](#getting-started) {#getting-started}
|
||||
|
@ -14,6 +14,7 @@ Here are some Getting Started guides for different operating systems:
|
|||
<!-- TODO detect current OS with browser and only show link for that, provide other button for others -->
|
||||
|
||||
- [Linux x86-64](https://github.com/roc-lang/roc/blob/main/getting_started/linux_x86_64.md)
|
||||
- [Nix Linux/MacOS](https://github.com/roc-lang/roc/blob/main/getting_started/nix.md)
|
||||
- [MacOS Apple Silicon](https://github.com/roc-lang/roc/blob/main/getting_started/macos_apple_silicon.md)
|
||||
- [MacOS x86-64](https://github.com/roc-lang/roc/blob/main/getting_started/macos_x86_64.md)
|
||||
- [Windows](https://github.com/roc-lang/roc/blob/main/getting_started/windows.md)
|
||||
|
|
|
@ -2076,8 +2076,8 @@ Here are various Roc expressions involving operators, and what they desugar to.
|
|||
| `a && b` | `Bool.and a b` |
|
||||
| <code>a \|\| b</code> | `Bool.or a b` |
|
||||
| `!a` | `Bool.not a` |
|
||||
| <code>a \|> b</code> | `b a` |
|
||||
| <code>a b c \|> f x y</code> | `f (a b c) x y` |
|
||||
| <code>a \|> f</code> | `f a` |
|
||||
| <code>f a b \|> g x y</code> | `g (f a b) x y` |
|
||||
|
||||
|
||||
</section>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue