СоХабр закрыт.

С 13.05.2019 изменения постов больше не отслеживаются, и новые посты не сохраняются.

H Loli — новый высокопроизводительный язык в черновиках Recovery Mode

В этой статье мы поговорим о новом интерпретируемом языке Loli, рассмотрим синтаксис и сравним с языками C и Python.



Введение


Loli это форк языка lily. Язык loli по синтаксису больше всего похож на Python. Но по производительности в разы быстрее.
Loli строго типизированный язык. В нём так же присутствуют объекты. То есть Loli одновременно и функциональный и объектный язык. И это несомненно плюс. Расширение файлов у языка это .li.
Loli имеет возможность написания расширений на C.


Тесты производительности


Итак, я не наврал про его производительность, ведь она действительно высокая.
Я написал одинаковые тесты производительности на C, Python и Loli. Тесты на github


Результат вы видите сами:





Небольшой пример


Пример вычисления факториала:


#[
     Loli строго типизирован, поэтому нужно описать каждую переменную своим типом или классом
]#

fn fact(num: Integer): Integer {
    if (num <= 0): {
        raise IndexError("Number <0") # Если num меньше нулю, то выбрасываем исключение
    }

    if (num <= 1): {`
        return 1 # Если <= 1 то возвращаем 1 
    }

    return num * fact(num - 1) # Ну а тут умножаем num на рекурсивный вызов fact с num - 1 
}

sayln(fact(5)) # Вызываем нашу функцию и даём ей на вход число 5, ответ 120

Синтаксис


Ну а теперь давайте рассматривать синтаксис языка с самого начала.


Переменные:


var x = 5  # Авто-определение типа переменной
var y: Double = 5.32  # Определение типа в ручную
var z = [1, 2, 3], hi = "Hello, world!" # Создание множества переменных через запятую

Массивы:


# List
var a_list = [1, 2, 3]
var a_range = range(1, 3)
var empty_list: List[Double] = []

# Hash
var a_hash = ["a" => 1, "b" => 2, "c" => 3]
var empty_hash: Hash[String, Integer] = []
# Hash от List отличается только тем что можно создавать ключи определённого типа

#[
      Tuple это как List только Tuple. Tuple имеет фиксированный размер и может содержать типы, которые не имеют никакого сходства друг с другом 
]#
var a_tuple: Tuple[String, Double] = <["hi", 34.93]>

Как видим массивы очень интересны, но так же интересны и строки:


# Всё это один тип String
var hi = "Hello, world!"
var multi_line = """Hello, \
                    world!"""

#[ 
    А это уже ByteString, единственное их отличие в том что они хранят в себе массив байтов.
    Так же обычные строки можно переводить в ByteString методом to_bs
    Конструкция типа var a = "Hello".to_bs() тоже будет иметь свой смысл. 
]#
var a = b"123456"
var b = b"\0\1\2"
var c = b"\255\254\t"
var d = b"""A \
    multi-line \
    ByteString"""

Со строками разобрались, теперь числа.
Под капотам в C у типа Integer стоит uint64_t, то есть 64-битные числа.
У Byte это uint8_t, то есть 8-битные числа.
Ну а у Double соответственно double.


Теперь поговорим о функциях:


# Функции
fn empty_fn {
     sayln("Hello, World!") # Функция без аргументов и возвращаемого значения 
}

fn fn_with_arg(num: Integer) { # Функция с обязательным аргументом 
     sayln("Num: " ++ num) # ++ в Loli это не инкремент, а соединение типов
}

fn fn_with_arg_and_return(num: Integer): Integer {
      return num # Возвращаем num 
}

fn fn_without_arg_but_with_return: Integer {
      return 2 + 2
}

# Функция с Keyarg
fn sample(:first x: Integer, :second y: Integer, :third z: Integer): Integer {
  return x + y + z
}

sample(1, 2, 3) # 6
sample(1, :second 2, :third 3) # 6
sample(:third 30, :first 10, :second 5) # 45

# Не обязательные значения функций
# В данном случаи можно просто вызвать sample() и a будет равна 10
fn sample(a: *Integer = 10): Integer { 
  return a + 10 
}

# Varargs
fn sum(n: Integer...): Integer { # В данном случаи n будет типом List[Integer]
  var result = 0
  n.each(|x| result += x) # Лямбда функция
  return result
}

# Лямбда функции
fn apply(a: Integer, fn: Function(Integer => Integer)): Integer {
  return fn(a)
}

sayln(apply(10, (|a| a * a))) # 100 

# Future функции
future fn add(Integer, Integer): Integer { ... }

# *a lot of code*

fn add(x: Integer, y: Integer): Integer {
  return x + y
}

Такс, с функциями мы разобрались, ну а теперь классы.


# Класс Point с двумя аргументами в конструкторе
class Point(x: Integer, y: Integer) {
  pub var @x = x  # pub означает что это поле публичное, так же есть pri (private), pro (protected) 
  pub var @y = y
}

# Можно также сократить предыдущий пример
class Point(pub var @x: Integer, pub var @y: Integer) {  }

# Наследование
class Point2D(pub var @x: Integer, pub var @y: Integer) {}
class Point3D(x: Integer, y: Integer, pub var @z: Integer) < Point2D(x, y) {}  

#[
      По умолчанию методы класса получают неявный параметр self в качестве первого аргумента. 
      Спецификатор sta при применении к методу класса отключает это поведение
]#

# Дженерики
class Stack[A](element: A) {
  pub var @contents = [element]

  pub fn push(value: A): self {
    @contents.push(value)
  }
}

Stack(1).push(2).push(3) # [1, 2, 3]

Классы прошли, теперь рассмотрим исключения. Исключение это обыкновенный класс который унаследован от класса Exception. В loli по умолчанию уже есть 7 исключений которые можно использовать.


  • Exception — базовый класс всех исключений
  • DivisionByZero — ошибка деления на 0
  • IndexError — Доступ за пределы контейнера (например, List), String или ByteString
  • IOError — Некорректная работа с файлами
  • KeyError — Попытка прочитать значение из Hash, которое не существует
  • RuntimeError — Неправильное действие во время выполнения, например изменение хеша во время итерации или превышение предела рекурсии
  • ValueError — Указано неверное или необоснованное значение

Все исключения можно вызвать через ключевое слово raise


raise IndexError("Index out of range") # Тут мы создаём экземпляр класса унаследованного от Exception

Для отлова исключений существует блок try\except


try: {
  raise IndexError("Index out of range")
except Exception as e:
  sayln("Exception: {0}".format(e.message))
}

Импорты


Система импорта похожа на ту что в Python:


import sys

sys.exit()

import package

import package as pkg

import (somefn, somevar) package

import "folder/package"

Пути импортов в loli выглядят таким образом:


./<name>.li
./<name>.(dll/so)

./pkg/<name>/<name>.li
./pkg/<name>/<name>.(dll/so)

<original root>/pkg/<name>/<name>.li
<original root>/pkg/<name>/<name>.(dll/so)

Enums


Небольшой пример enum:


enum Rgb {
  Red,
  Green,
  Blue

  fn is_blue: Boolean {
    match self: {
      case Blue: return true
      else:      return false
    }
  }
}

Заключение


Как мы видим Loli это очень хороший и быстрый скриптовой язык который можно бесконечно расширять расширениями на C. На Loli уже есть биндинги OpenGL и FreeGLUT и обёртка над cURL. А так же в разработке биндинги GTK+. Так же планируется написать HTTP сервер для loli. Из этого следует что язык можно применять в разных сферах. Я надеюсь вам понравился этот язык и вы уделите ему немного времени.


Ссылки


+19
~45100

комментарии (131)

+2
+3 –1
Mercury13 ,  
Я и сам думал о чём-то таком. И, вижу, идея витает в воздухе, и люди сделали.
+4
+5 –1
bolk ,  
Cython уже существует, зачем его делать?
0
ProRunner ,  
2 статьи опубликованы примерно в одно время, ссылка для связи:
habr.com/ru/post/441466
0
alsoijw ,  
Уже скрыта в черновики
+4
kzhyg ,  
KeyError — Попытка прочитать значение из Hash, которое не существует

Протестую! Это не ошибка, а нормальный сценарий использования!
Связанный вопрос: null есть?

0
MWGuy ,   * (был изменён)
Есть, но его можно встретить только при вызовах функций. То есть это тип данных Unit
+4
bormotov ,  
если идеи черпали в питоне — там как раз KeyError. Для «нормального сценария» есть get()
+4
+6 –2
Suvitruf ,  
Loliвысокопроизводительный язык (¬‿¬ )
+17
+19 –2
khim ,  
Осталось понять: зачем? Сделать-то новый язык не смертельно сложно, но в таких случаях полезно понять чем старые не устраивают. Всякие Go и Rust'ы… Когда нам обещают «высокопроизводительный язык» и после этого показывают бенчмарк, в котором C оказывается в несколько раз быстрее… оно как-то не убеждает…

А вот про это в статье — ни слова.
+4
+5 –1
MWGuy ,  
Это интерпретируемый язык, а C здесь как сравнение между интерпретируемыми и компилируемыми языками. В данном случаи Loli действительно высокопроизводительный язык в сегменте интерпретируемых языков
+2
+4 –2
khim ,  
Вообще-то беглый взгляд показывает, что он такой же интерпретируемый, как какой-нибудь Groovy. И лишь чуть-чуть более скриптовый, чем go.

Если вам нужны скрипты — для этого совершенно не нужно разводить спецязыки в современном мире…
+8
+11 –3
saboteur_kiev ,  
Как мы видим Loli это очень хороший и быстрый скриптовой язык который можно бесконечно расширять расширениями на C.


А чем плох, например, bash, который тоже хороший скриптовый язык, который можно бесконечно расширять расширениями на С (и которых уже написано много)
–3
+1 –4
ZyXI ,  

Какие расширения на C у bash? Сторонние программы — это не расширения, они исполняются в другом процессе, что обеспечивает огромный overhead при каждом использовании. Я знаю, что zsh умеет во время исполнения подгружать дополнения‐библиотеки (.so), в которых можно определять команды (и не только), реализация которых исполняется в том же процессе, что и оболочка. Даже как‐то написал одно. Не слышал, чтобы такое умел bash и, особенно, чтобы у bash’а было много расширений на C.

+4
saboteur_kiev ,  
Вот весь процесс, который требует производительности выносим в отдельный процесс и все…
+4
+5 –1
siziyman ,  
Безотносительно сабжа, bash — абсолютно отвратителен и создаёт больше проблем, чем решает, как только ваш скрипт обрастает сколько-то сложной логикой и/или по длине становится, условно, больше экрана-двух. Его практически невозможно человечески дебажить, сложно делать действительно переносимым, синтаксические особенности шеллскриптов (кавычки с разным экранированием, магия разных GNU-расширений) крайне неочевидны для тех, кто не очень хорошо знаком с языком, и даже просто визуально трудноразличимы иногда. Читать шеллскрипты — тоже сомнительное удовольствие.
+1
0xd34df00d ,  
А когда ошибки типов определяются, кстати?
0
MWGuy ,  
Ещё до исполнения
+5
0xd34df00d ,  
Интерпретируемый язык с отдельной фазой тайпчекинга — это интересно! В особенности интересно, почему тогда не прикрутить и компиляцию.
0
staticlab ,  

А с какими языками кроме Питона вы его сравнивали?

+4
+5 –1
geoolekom ,  
Все остальные языки имеют фатальный недостаток
+2
maxzhurkin ,  
На Loli уже есть порт OpenGL и FreeGLUT и обёртка над cURL. А так же в разработке порт GTK+
почему вы называете биндинги портами?
0
+1 –1
MWGuy ,  
Не знаю. Сейчас поправлю
0
maxzhurkin ,  
порт GTK+
–4
+3 –7
ntkj666 ,  

"Не большой".

0
+1 –1
MWGuy ,  
Это уже исправлено
+3
+4 –1
QtRoS ,  

Многопоточность не раскрыта, непонятно есть ли что-то наподобие GIL или нет.
Язык без крупной конторы за спиной почти обречён на провал… Из таких, разве что Julia из недавних может выстрелить, так как имеет конкретную нишу.

–1
+1 –2
MWGuy ,  

Много поточность есть как отдельный модуль. Ибо не всем она нужна по умолчанию.
https://github.com/loli-foundation/loli-threads


Пример:


import threads

fn thread_function {
    sayln("Hello, from new thread!")
}

var thread = threads.create(thread_function)

if (threads.join(thread) == 1): {
    sayln("Error joining thread!")
}
+1
a-tk ,  
Всё равно тема GIL не раскрыта.
+5
+7 –2
khim ,  
Для языка программирования нужна «свободная ниша». Грубо говоря какое-то количество разработчиков, которым, по тем или иным причинам, не подходят другие языки. Скажем то, что PHP можно встравивать в HTML — это ерунда, он взлетел не поэтому, а потому, что mod_php позволял людям сделать «хостинг со скриптами за три копйки». Сейчас времена изменились и эта ниша уже не требует тех компромиссов, на которые когда-то пришлось пойти разработчикам PHP.

Аналогично с C (== язык для написания софта под Unix изначально) и со всеми другими популярными языками.

А «крупная контора» (или, как альтернатива, «крупный проект») создаёт такую нишу более-менее автоматически: хотите работать с нами — изучите вначале Brainfuck!
+1
+2 –1
QtRoS ,  

Я не уточнил, что в наше время. Время, когда даже студент с помощью llvm может написать вполне промышленный язык, но и все нишевые языки существуют и устаканилось, "свободных касс" не осталось, а та самая Джулия была названа потому, что в математике ниша пустует — есть унылый матлаб, всякие неполноценные мэйплы, а где-то вообще фортран используется...

0
+1 –1
khim ,  
Я не спорю по поводу Julia. Не знаю чем кончится, но да — ниша куда она пытается влезть есть и она таки пустует (Python — это всё-таки не совсем те).

А вот куда пытается влезть Loli?
0
funny_falcon ,  

Я бы взял Loli как скриптовый язык для in-memory стораджа, т.к. единственный вменяемый конкурент убог и не имеет статической типизации (Lua). Но это если метапрограммирование на высоте.

+10
funny_falcon ,  

А вот и оригинал языка, который автор выдает за свой: https://gitlab.com/FascinatedBox/lily

+8
4p4 ,  

Дифанул несоклько рандомно выбраных файлов из обоих репозиториев. Разница на уровне sed s/loli/lily/g плюс выпиленые коментарии.

+2
tongohiti ,  
Ого, разоблачения подвезли.
+2
MechanicZelenyy ,  
Смешали синтаксис Питона и Котлина, добавили статическую типизацию. Ну а дальше что?
+1
+3 –2
MWGuy ,  
Планируем Web, и Desktop
+1
bormotov ,  
Desktop? У вас есть прям очередь «чего нужно написать» для десктопа? И там питон с pyqt не справляется? Или java+javafx, а соответственно всё jvm+javafx.
На прошлой работе, когда встал вопрос про «нужно приложение» — взяли scalafx и написали.

На мой субъективный взгляд, перспективы так себе. Язык как таковой — это порядка 20% всего, что нужно. Если посмотреть ближайшие 10-15 лет, новые языки или живут на уже готовой экосистеме (кажется, чаще всего это jvm, потом llvm), или их создают монстры типа гугла, понимая, что за год-два они потянут развить экосистему до уровня «этим есть смысл пользоваться».

Все остальные остаются в нишах.

Кстати, кажется web для подавляющего большинства это javascript и вариации на тему.
+12
+13 –1
rumkin ,   * (был изменён)

Вы разработали язык за полтора месяца. Это круто и похвально. Импонирует строгая типизация, подсчет ссылок и минималистичный синтаксис.


По поводу статьи:


  1. Исправьте орфографические ошибки: "джинерики", "по этому" и т.п.
  2. Опишите подробнее отличительные особенности языка по пунктам. Чем он отличается от встраиваемых конкурентов, например того же lua. Сама по себе производительность на единственном синтетическом тесте не убедительный показатель, нужно больше разных кейсов. В репозитории указано "It can be embedded into HTML code " – это мне кажется наиболее интересной особенностью, которая не раскрыта.

По поводу языка:


  1. Синтаксис можно улучшить, например кортежи лучше обрамлять круглыми скобками, вместо <[ ]>, ИМХО это уже негласный стандарт.
  2. Конструкция if-elif-else построена по странному принципу. Лично мне ближе конструкция keyword (expression|tuple|statement)? block, которая имеет свойства фрактала и воспроизводится во всем языке:
    if () {}
    else {}
    function () {}
    try {}
    catch () {}
  3. Синтаксис больше похож на C-style с примесью Python, чем на Python.
  4. Классическое ООП в 2019 выглядит архаично и не вызывает особого интереса. Посмотрите на Rust, Swift, Go в них заложены более перспективные парадигмы. Даже JS скоро обрастет функциональными возможностями: паттерн матчинг, пайпинг, декораторы.
  5. sayln, прям вообще не заходит, с моей точки зрения лучший вариант – go. В нем используется пакет Fmt, который импортируется явно (явное лучше неявного).

Желаю успехов.

+1
MWGuy ,   * (был изменён)

Спасибо за отзыв! Я постараюсь написать больше синтетических тестов.
На счёт "It can be embedded into HTML code": мы ещё разрабатываем эту фишку, она будет нужна для написания web сайтов, подобно php.


Конструкция if elif else немного не стандартная:


if (num == 1): {
      return 1
      else: {
             return 2
      }
}
0
mSnus ,  
зачем двоеточие после скобок? читаемость не улучшает
+18
funny_falcon ,  

Странно, что автор сам за себя не ответил, но языку больше, чем полтора месяца.
Я на него натыкался еще пару лет назад.
Не понятно, зачем им потребовалось переносить репозиторий и переписывать историю коммитов.


А, кажется я понял: потому что оригинал назывался lily: https://github.com/FascinatedBox/lily/blob/master/README.md


Что я могу сказать: не красиво брать чужие исходники и выдавать их за свои.

+4
rumkin ,  

Спасибо, что сообщили. Очередной BolgenOS.

+8
aNNiMON ,  
Программисты на Loli — лоликонщики?
0
MWGuy ,  
Не знаем. Но эта шутка уже всплывала у нас в беседе, и не раз.
+1
lain8dono ,  

Один вопрос: почему именно Цукихи?

+2
MWGuy ,  
Просто нам она понравилась
+3
divanikus ,  
0
+1 –1
FreeNickname ,  
+1
+2 –1
dmitry_dvm ,  
var y: Double = 5.32 # Определение типа в ручную

А зачему тут var?
0
MWGuy ,  
var — ключевое слова для обозначения переменной, к слову констант в Loli нету
+5
kmansoft ,  
Если это простой язык нацеленный на встраивание — то напрашивается сравнение с Lua и в том числе с LuaJIT. Здесь JIT или компиляция или чисто интерпретатор?
0
MWGuy ,  
Тут простой, но быстрый интерпретатор. Так же тут используется GC для сборки мусора
+10
timdorohin ,   * (был изменён)
Сравните по скорости с LuaJIT, пожалуйста. Вероятно, будете удивлены.
И сравнивать стоит и с режимом интерпретации, и с JIT.
+9
Kroid ,  

Ещё один язык?)


Go умеет в параллельность — легковесные потоки, взятые у erlang'а. Плюс компилируемый язык высокого уровня.


Rust — "современная реинкарнация си".


Elixir — это erlang на колёсах.


А loli зачем нужен? В 3 раза быстрее питона? Ну так все важные операции на питоне давно делаются через сишные либы. Не увидел как-то из статьи, какую проблему он решает.

+1
+3 –2
txlyre ,  

Loli подходит там, где нужен быстрый, легковесный и просто встраиваемый скриптовый язык. Например, как тот же самый Lua, только Loli, в отличие от Lua, легче расширять.

+5
funny_falcon ,  
Ты не ответишь, почему ты выдаёшь слегка переделанные чужие исходники за свои?
+1
+2 –1
bolk ,  
Раст — всё же Си++, а не Си. Гоу больше Си, в таком случае.
+2
+3 –1
khim ,  
Go — вот ни разу не Си. Или, может, не совсем тот Си. Не забывайте, что Си, изначально, это — язык для написания операционки. Rust на эту нишу претендует (хотя не факт, что займёт), Go — нет. Совсем нет.
+2
+3 –1
Doverchiviy_kot ,  
Осталось написать новый интерпретируемый язык tv.major основанный на loli и js.
Заголовок спойлера
шутка юмора.
+1
pcCallJG ,  
а я свой яп для диплома пишу… на расте с возможностью импорта сторонних либ и понятным синтаксисом :)
+8
FreeNickname ,  
А там будет модуль, чтобы грабить корованы?
+3
TonyLorencio ,  

Джва года ждал такой модуль

+2
Zanak ,  
В общем и целом, я за эксперименты с разработкой новых языков. Большая часть этих людей и проектов уйдет в историю, ни чего после себя не оставив. Но вот те, кто не бросит это занятие, рискуют вписать свое имя в историю, наряду с такими людьми как Бьёрн Страуструп, Ларри Уолл, Гвидо ван Россум, Юкихиро Мацумото и еще массой народу. Поэтому, я желаю участникам этого проекта терпения и удачи.
А теперь немного о том, за что глаз зацепился:
— есть тип данных ByteString, а как у вас обстоят дела с поддержкой юникода?
— я бы не стал использовать символ '\' для строк в тройных кавычках, если конечно вы подразумевали под ними многострочное значение, на мой взгляд это черезчур.
— тип данных целое:
12345
-67890
0c744
x0xFF
0b101010101

первый и второй пример понятны, последний, судя по всему двоичное представление, а вот в 3 и 4 примере точно нет опечатки в документации?
— похоже, операторы у вас работают только с числовыми типами, а как обстоят дела со строчными операциями, хотя бы со склейкой, для примера?
— с интерполяцией переменных вообще не понял, возможно стоит добавить пример в документацию.
— на своеобразие синтаксиса if/elif уже обращали внимание.
— про enum, я могу в перечислении задать не только названия, но и значения:
enum Rgb {
  Red = "#ff0000",
  Green = "#00ff00",
  Blue = "#0000ff"
}
как — то так?
–1
MWGuy ,  

Как я и говорил в статье у нас 64 битные числа, а 0c744 и x0xFF это шестнадцатеричная система счисления.


Склейка производится с помощью оператора ++


sayln(5 ++ 6)
var a = 6 / 2
sayln("Hello: " ++ a)

Результатом будет:


56
Hello: 3

В enum нельзя записать значения, но можно писать свои методы.

+2
oldd ,   * (был изменён)
Заинтересовало, какой умственный смысл в переименовании жуткостандартной функции println, которая знакома всем с первых строк в программировании, в слово «sayln». Ведь должен же быть какой-то посыл? -2 буквы?
И серьёзный вопрос — как насчёт встраивания в качестве скриптового языка? Ищё замену groovy для работы без jvm
0
MWGuy ,  
Встраивать язык действительно можно, для этого есть libloli.(so/dll). Ну а потом двигаться от этого файла
+2
txlyre ,  
  1. Тип String, а так же идентификаторы поддерживают UTF-8.


  2. «\» означает, что нужно экранировать перенос текущей строки, а так же табуляции и/или пробелы в начале следующей строки:
    \<newline>: ByteString and String only. The newline of the current line and the leading whitespace (' ' or '\t') will be omitted from the literal. (из документации)


  3. Третий пример — восьмеричное число, а в четвёртом, действительно, опечатка, должно быть «0xFF».


  4. Для конкатенации используется оператор «++».


  5. Интерполяция производится либо с помощью оператора «++», либо с помощью метода String.format.


  6. Данный синтаксис был выбран потому, что он лучше всего вписывался в общий стиль языка.


  7. Нет, на данный момент в enum нельзя задавать значения.


+1
staticlab ,  
рискуют вписать свое имя в историю

Как Денис Попов?

+25
tongohiti ,  
Расширение файлов у языка это .li.

Ждал, что расширение будет .lol
+8
ainoneko ,  
Расширение файлов у языка это .li.
Ждал, что расширение будет .lol
Вероятно, не попало под замену "s/lily/loli/g"
¯\_(ツ)_/¯
0
Bookvarenko ,   * (был изменён)
Хотелось бы узнать, насколько он хорош в трассировке лучей. Все эти реймаршинги, шейдеры, вектоы, математика и прочее такое.
+1
MWGuy ,  
Еще не писали такого, но обязательно напишем
+3
saluev ,  
Заглянул в спиcок контрибьюторов, а там FlightBlaze. Привет его проекту браузерного движка с нуля (репозиторий он, видимо, скрыл).
0
FlightBlaze ,  
Вот во что кстати превратился проект браузерного движка с нуля http://newtoo.ru/magenta/ru
+1
QtRoS ,  

Мне было интересно во что, но из url'а ничего непонятно :)

+1
MechanicZelenyy ,  
А там и из сайта ничего не понятно, вместо ссылок пока болванки.
+1
+2 –1
geoolekom ,   * (был изменён)
> в ручную
> под капотам
> не обязательные значения функций

Следует вычитывать статью перед публикацией.
+1
ieiunium ,  
Нишево ваш язык очень напоминает выше упомянутую Julia. Знакомы ли вы с Julia, и знаете ли какие преимущества вашего языка перед Julia?
0
+1 –1
MWGuy ,  
Лично я на нём не писал, но о нём слышал
+1
gchebanov ,  
Но по производительности в разы быстрее

У меня append в списку интов работает в python и loli-lang с примерно одинаковой скоростью.
Делаю 10^7 раз в цикле.
Это питон быстрый или у loli есть пространство для оптимизации?


$ g++ -O3 -o hw hw.cpp && time ./hw
test cpp: 0.139714 Seconds
./hw  0.08s user 0.07s system 94% cpu 0.156 total

$ time python3 ./hw.py
test Python:  0.7941131591796875  Seconds
python3 ./hw.py  0.82s user 0.05s system 98% cpu 0.889 total

$ time ./loli hw.li
test Loli: 0.891672 Seconds
./loli hw.li  1.45s user 0.11s system 99% cpu 1.578 total

P.S. code

0
+1 –1
MWGuy ,  
Мы в loli ещё не всё оптимизировали просто=)
–1
domix32 ,   * (был изменён)
Почему бенчмарки отдельной репой?
0
bodqhrohro ,  
Только я не понимаю, при чём тут питон?
+7
staticlab ,  

Потому что среди интерпретируемых языков он довольно медленный. Удобно сравнивать производительность :)

+1
saboteur_kiev ,  
И не самый удобный, я бы сказал.
Питон оказался востребованным из-за огромного количества готовых библиотек из коробки.
+2
bodqhrohro ,  
Я не про сравнение, я про заявление:
Язык loli по синтаксису больше всего похож на Python
Ничего явно питонистого здесь не вижу.
0
dimka11 ,  

Интересно за счёт чего? Там же все равно используется JIT, как в большинстве других языков, или далеко не везде?!

+1
shaukote ,   * (был изменён)
Насколько я знаю, CPython (эталонная реализация) так и не использует JIT. Есть PyPy, но с ним обычно никто не сравнивает. :)
+6
eggstream ,  
Господа авторы новых языков программирования, скажите, это специально фишка такая — делать привычные вещи непривычным синтаксисом? а привычным синтаксисом — странные действия? Почему каждый считает своим долгом изобрести собственное сокращение для public function и else if, по-своему назвать ключевые слова (throw -> raise, catch -> except) или на синтаксис инкремента навесить конкатенацию с приведением типов?
Раздражает также неконсистентное употребление скобок/двоеточий в условных блоках и прочие странные нестыковки
0
Sirikid ,  
А вы хотите чтобы каждый новый ЯП был языком икс?
+4
eggstream ,  
Ни в коем случае. Просто хочется консистентности и «наименьшего удивления». Один из основных принципов дизайна должен работать и в дизайне ЯП — Похожие действия должны иметь похожий интерфейс и наоборот — разные действия не должны иметь похожего интерфейса
+3
Sirikid ,  

Очень субъективные критерии, для вас привычней throw и catch, а для питонистов raise и except.

0
YemSalat ,   * (был изменён)
Тоже о подобном думал, выглядит весьма неплохо, в некоторых моментах синтаксис можно поменять/улучшить. Идея хорошая, как мнe кажется.
+1
ainoneko ,  
Если num меньше или равен нулю, то выбрасываем исключение
«LOL WUT?»
Ноль факториал вообще-то равен единице.
+2
apapacy ,  
github.com/LoLi-Lang/LoLi регистр имеет значение.
0
+1 –1
MWGuy ,  
Это не наш репозиторий, на github.com/loli-foundation/loli
+1
ainoneko ,  
Ещё с виртовским языком надо не перепутать (он хотя бы одной буквой отличается).
+3
impwx ,  
Хороший дебют. Хотя вы и написали очередной велосипед, но видно, что подошли к вопросу очень серьезно, в отличие от недавно обсуждавшегося на Хабре языка-пюре (если не считать названия, хехе).

Есть несколько вопросов по существу:

1. Насколько я понял, VM регистровая: почему не стековая?
2. Зачем нужны двоеточия в конструкциях типа if(...): { ... }? Это же чисто визуальный шум.
3. Есть ли редактор с автокомплитом или хотя бы планы сделать такой? Практика показывает, что без удобной среды разработки новый вело-язык гарантированно не взлетит. Советую посмотреть в сторону реализации Language Server Protocol, чтобы можно было встроить поддержку в современные редакторы типа VS Code.
4. Идея о встраивании кода в HTML-разметку, имхо, провальная. Логика и представление должны быть разделены, и для этого есть множество удобных шаблонизаторов. Не нужно поощрять написание кода в стиле похопе.
+8
Flux ,  
Хороший дебют.

Скорее позорный плагиат и попытки форса чужой работы выданной за свою, сопровождаемые нелепыми отмазками «автора» в стиле «мы никогда не слышали про тот язык, код совпадающий с точностью до замены подстрок получился случайно и естественно».

Тут вообще полный набор провальности — плагиат, неуважение к умственным способностям читателя, аниме, неграмотность автора и явная ложь — болгенос 2.0, короче. Похоже «автор» просто любит внимание.

А ведь достаточно было проставить ссылку на оригинальную реализацию и все было бы хорошо.
+3
impwx ,  
Уже вижу. Беру свои слова назад. Жаль, что чуда не случилось.
+31
+32 –1
funny_falcon ,  

Очень жаль, что автор взял чужие исходники, и не упомянул, откуда. Это называется плагиатом.
https://github.com/FascinatedBox/lily

+17
funny_falcon ,  
–28
MWGuy ,  
Имхо обвинять в плагиате, ибо мы писали всё с нуля сами. А про такой репозиторий некогда не слышали
+17
mayorovp ,  

Ага, конечно же с нуля!


Вот это — ваш код:


typedef struct loli_bytestring_val_ loli_bytestring_val;
typedef struct loli_container_val_  loli_container_val;
typedef struct loli_coroutine_val_  loli_coroutine_val;
typedef struct loli_file_val_       loli_file_val;
typedef struct loli_foreign_val_    loli_foreign_val;
typedef struct loli_function_val_   loli_function_val;
typedef struct loli_generic_val_    loli_generic_val;
typedef struct loli_hash_val_       loli_hash_val;
typedef struct loli_string_val_     loli_string_val;
typedef struct loli_value_          loli_value;
typedef struct loli_vm_state_       loli_state;

А вот это — lily:


typedef struct lily_bytestring_val_ lily_bytestring_val;
typedef struct lily_container_val_  lily_container_val;
typedef struct lily_coroutine_val_  lily_coroutine_val;
typedef struct lily_file_val_       lily_file_val;
typedef struct lily_foreign_val_    lily_foreign_val;
typedef struct lily_function_val_   lily_function_val;
typedef struct lily_generic_val_    lily_generic_val;
typedef struct lily_hash_val_       lily_hash_val;
typedef struct lily_string_val_     lily_string_val;
typedef struct lily_value_          lily_value;
typedef struct lily_vm_state_       lily_state;

Я, конечно, понимаю что типы запросто могли оказаться названы похожим образом просто потому что таков их смысл — но каким таким образом они могли независимо оказаться написаны в том же самом порядке?

+3
timdorohin ,   * (был изменён)
Порядок самый обычный, алфавитный?

UPD: Да, поначалу думал на автогенерированные заголовки, но слишком уж похоже. Что-то тут не чисто.
+6
+8 –2
mayorovp ,  

Ага, особенно алфавитно получилось с lily_string_val, lily_value и lily_state.


Там ниже еще блок функциональных типов lily_destroy_func, lily_import_func, lily_render_func и lily_call_entry_func, а потом структура lily_config. Кстати, у последней имена и порядок полей тоже совпадают.

+15
timdorohin ,   * (был изменён)
Ага, особенно алфавитно получилось с lily_string_val, lily_value и lily_state.
Если смотреть по lily_string_val_, lily_value_ и lily_vm_state_ то именно что по алфавитному.

Но да, совпадений слишком много. Это уже не совпадения, а фиг его знает что. Такой жЫрноты со времен болгеноса не было…
+2
+3 –1
Flux ,   * (был изменён)
MWGuy товарищ вор, не прокомментируете ли чудесные совпадения приведенные в комментарии выше как-то кроме «мы совершенно независимо написали код идентичный вплоть до автозамены»?

P.S. сеть помнит все — закрывать issues о плагиате и удалять неугодные комменты просто потому что захотелось — сомнительная практика.
image
+2
funny_falcon ,  
Там были не совсем приличные комментарии :-)

В любом случае, MWGuy принял правильное решение, и вернул упоминание автора в лицензии:
github.com/loli-foundation/loli/blob/fa8f88a63b9be01dc9e0edf3825a6f9e287b1017/LICENSE

Я бы посоветовал им объединиться с оригинальным автором, раз уж они оценили преимущества технологии. Но решать, конечно, им.
+24
kzhyg ,  
Как вы прокомментируете полное, вплоть до пустых строк, совпадение явно не автосгенерированных файлов?
github.com/loli-foundation/loli/blob/master/src/loli_vm.c
gitlab.com/FascinatedBox/lily/blob/master/src/lily_vm.c
+1
impwx ,  
+1
+4 –3
MWGuy ,  
Проанализировав ситуацию, и наказав главного разработчика (уже нет), я укажу авторство, и что это форк. А также извиняюсь в своей не правоте ибо этот язык в первый раз вижу. Надеюсь на ваше понимание
+3
+4 –1
Suvitruf ,   * (был изменён)
У вас там коммиты с Января. Как вы его можете «первый раз видеть»? О_о
+2
staticlab ,  

MWGuy делал только инфраструктурные правки. Основную часть кода "писал" txlyre.

+3
impwx ,  
А смысл теперь выгораживаться за счет главного, кхе-кхе, «разработчика»? История уже достаточно широко разлетелась, язык крепко встал в один ряд с BolgenOS и Антивирусом Бабушкина.
+1
mayorovp ,  
Осталось вернуть вырезанные из кода комментарии на место, и добавить потерявшуюся строчку в файл LICENSE…
0
amarao ,  
Напишите это в преамбуле к статье. Пока что всё ещё выглядит сильно некрасиво.
+2
WraithOW ,  
наказав главного разработчика

А вы там какой? Очень главный? Супер главный?
+12
Anarchist ,  

Назвали бы уж честно — BolgenLang. :)


Кроме плагиата, язык выглядит приветом из прошлого. Мутабельность во всех щелях, нуллы, исключения...

0
nikudyshko ,  
if (num <= 0): {
        raise IndexError("Number <= 0") # Если num меньше или равен нулю, то выбрасываем исключение
    }

Если мне не изменяет память — факториал нуля равен единице, а не ошибке
–1
MWGuy ,  
Да, небольшая опечатка=)
+7
captain_obvious ,  
http://loli-lang.ml/?#welcome:
loli
Operators
Basic arithmatic operations (+ — * /) can be used for two Double values, or two Integer values, or when there is one Double and one Integer value.
The result is a Double if either side is a Double, Integer otherwise. Other primitive operations (shifts, bitwise operations, and modulo) are only valid if both sides are Integer.

Comparison
Comparison operations (>= > < <=) are allowed on any two sets of Integer, String, or Double.
Equality operations (== !=) are allowed on any two equivalent types.
Simple values like Integer, and Double are straightforward: They are equal only when they are the same value.
List, Tuple, Hash, and variants use structural comparison.
All other containers and more interesting types use identity comparison. A comparison such as SomeClass(2, 4) == SomeClass(2, 4) will always return false, since each SomeClass is a different instance.

Interpolation
The ++ operator and String.format all make use of built-in interpolation. Interpolation works as follows:
Primitive values such as Integer, Double, and String have their content written out.
Built-in containers have their inner contents written out. Hash does not guarantee an ordering to the contents it writes out.
Non-scoped variants print just their name and their contents. Scoped variants print out the enum name and a dot first. Classes print out their address.


https://fascinatedbox.gitlab.io/lily-docs//tutorial-basics.html
lily
Operations
Basic arithmatic operations (+ — * /) can be used for two Double values, or two Integer values, or when there is one Double and one Integer value. The result is a Double if either side is a Double, Integer otherwise.

Other primitive operations (shifts, bitwise operations, and modulo) are only valid if both sides are Integer.

Comparison operations (>= > < <=) are allowed on any two sets of Integer, String, or Double.

Comparison
Equality operations (== !=) are allowed on any two equivalent types.

Simple values like Integer, and Double are straightforward: They are equal only when they are the same value.

List, Tuple, Hash, and variants use structural comparison. Since List uses structural comparison, [1] == [1] will always return true.

All other containers and more interesting types use identity comparison. A comparison such as Point2D(2, 4) == Point2D(2, 4) will always return false, since each Point2D is a different instance.

Interpolation
The ++ operator, String.format, and print all make use of built-in interpolation. Interpolation works as follows:

Primitive values such as Integer, Double, and String have their content written out.

Built-in containers have their inner contents written out. Hash does not guarantee an ordering to the contents it writes out.

Non-scoped variants print just their name and their contents. Scoped variants print out the enum name and a dot first.

Classes print out their address.

+3
staticlab ,  
arithmatic

даже опечатки одинаковые :)

+3
+4 –1
Szer ,  

В БолгенОС были хотя бы нескучные обои.
Какой позор.

–3
amarao ,  
При чём тут позор-то? Люди пытаются.
+4
Szer ,  

Вы выше каменты почитайте, язык — чистый плагиат, причём воры ПОКА ЧТО всё упорно отрицают.

+1
amarao ,  
Упс. Вчитался.

Мдя, некрасиво. Идеи можно тырить сколько угодно, а вот реюзать код без указания на источник — некрасиво, очень.
+5
amarao ,   * (был изменён)
UPD: Вчитался в комменты выше. Реальный плагиат, очень некрасиво.

Сразу комплект вещей, которые обязаны быть в любом новом языке, чтобы быть интересными:

1. Алгебраические типы данных и исчерпывающие выборы (match, который ругается, если один из случаев не обработан)
2. Генераторы? Если уж питон, то как без генераторов?
3. Лямбды с замыканиями или без?
4. Типажи? Мне кажется, правда должна быть где-то между duck typing и типажами раста (последние чуть менее удобным, чем duck typing).
5. Вопрос юникода плохо разобран. Каким образом гарантируется нормальная форма строк?
6. Остальные вкусности питона? Контекстные менеджеры, декораторы?
+3
Electrohedgehog ,  
Я написал одинаковые тесты производительности на C, Python и Loli.

mila@mila-pc


Мила?! Маким Тарасов логинится как mila?

[Место для шутки про мамин ноутбук.]

Вообще человек либо эпических масштабов масштабов тролль, либо не менее эпичный… гм, ну вы поняли. Судя по профилю 14 годиков а уже наказывает разработчиков.
0
alsoijw ,  
Мила?! Маким Тарасов логинится как mila?

[Место для шутки про мамин ноутбук.]
А в чём соль шутки? Что-то не то с именем пользователя?