Как стать автором
Обновить

Комментарии 61

Так это даже не zip, а переименованый rar
Спасибо! Действительно rar (делал архив через rar.exe, и по простоте душевной думал, что с расширением zip он и сделает zip). Переделал, теперь всё как надо.
Ограничений U# в конструкциях языка оказалось немного – это атавизмы goto и case goto, а также yield, не моделируемый адекватно в автоматическом режиме. Не рекомендуется (хотя и можно) использовать struct, есть нюансы с наименованиями – всё это подробно описывается в отдельном документе.

Рискую нарваться на негатив (т.к. не специалист), но yield и struct это вообще ключевые ключевые слова (keywords) в языке. yield может быть незаменим при работе с коллекциями т.к. без него не написать iterator methods. А без struct я даже не знаю. Я даже не говорю про всякие ништяки типа ref struct, unsafe. Не уверен что есть 1-к-1 соответствие в Java, а в Python тем более.


Как вишенка на торте — сегодня долго возился с кастомным аттрибутом, наболело, поэтому обратил внимание, — согласно документации класс Attribute не поддерживается, в Type только 4 элемента, что фактически значит что рефлексии нет (без понятия как это работает в Java, полагаю там должен быть аналог, про Python из-за отсутствия статической типизации — вообще хз).


Фактически реализована трансляция каких-то совсем базовых методов базовых типов в аналогичные на другом языке (читай правка синтаксиса). Я прекрасно понимаю аргумент simplified English, но таким способом достаточно сложный проект транслировать невозможно.


Вообще не понятно зачем транслировать в Python так как языки ну совсем разного класса. Java еще я могу понять, и то проблем куча.


Конечно я допускаю, что я абсолютно не прав, так как упустил какие-то важные пункты или просто не вижу кейсов, в которых это могло бы быть полезно.

1. При переводе некоторых чужих проектов я сталкивался с парой десятков yield, и они прекрасно переделывались на List. Хотя можно использовать #if JAVA вариант без yield… #else вариант с yeild #endif Да, есть пример бесконечного цикла, ну тут увы.
2. struct — в документации я подробно описал, что их не запрещено использовать, они переводятся в class, но есть нюансы при присваиваниях. Немного помучившись, в своём проекте я вообще отказался от struct. И что удивительно, на скорость выполнения это никак не повлияло, а я думал, что их использования в моём случае даст выигрыш. Так что можно использовать.
3. Атрибуты не поддерживаются (игнорируются) — ну да, чем то придётся пожертвовать
4. Reflection есть в небольшом объёме, который требуется мне (получить тип объекта, для типа список конструкторов, вызвать конструктор). Но этот список расширяем путём внешних настроек. Невозможно сразу съесть слона (системные классы). Помогите нам — выберите какую-нибудь полезную функцию C#, найдите аналог в Java и опишите.

Да, приходится за всё платить, и мне для кросспрограммируемости в своём проекте Pullenti пришлось кое что переделать. Например, отказаться от плагинного способа загрузки dll с анализаторами обработки текста. Но это мелочи.

Хотел посмотреть на ваш проект, но исходников открытых я так понимаю нет. Судя по тому, что я понял из демонстрационного проекта, в случае Pullenti описанного функционала U# должно хватить, а вот насчет более сложных (в смысле применяемых технологий) проектов — я не уверен.


Для меня больной темой например оказались аттрибуты и yield, т.к. существует огромная разница между
IEnumerable<T> YieldMethod<T>(/*...*/) {yield break;}
и аналогичному ему
List<T> ListMethod<T>(/*...*/) {/*???*/}
Первый позволяет потреблять элементы коллекции лениво, или же являться источником бесконечного количества элементов. List<> в свою очередь вполне себе конкретная структура данных.
Попробую привести пример:
InfiniteSourceOfInt().SomeYieldMethod().Take(5);
должен корректно отработать и в конечном счете вернуть некий IEnumerable<> из 5 элементов. А вот если
InfiniteSourceOfInt().SomeListMethod().Take(5);
то я полагаю здесь будет бесконечный цикл т.к. SomeListMethod должен проитерировать всю исходную коллекцию, чтобы сгенерировать List<>, а она бесконечная (ну или очень большая, например).


Сейчас обнаружил что typeof тоже не поддерживается, is и as находят свои аналоги, а вот type matching вида var x = "a_b_c" is string s ? s.Split('_') : throw new InvalidOperationException(); уже нет. Про pattern matching в case блоке вообще молчу.


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


Ограничений U# в конструкциях языка оказалось немного

на самом деле ограничений довольно много, и мне сложно представить как я бы писал U#-совместимый код.


P.S.: вовремя обновил страницу и увидел комментарий Vadem ниже


async/await, похоже, тоже не поддерживается.
А вот это уже критично.

В списке либ отсутствует Task, что ставит под вопрос трансляцию кода даже с малой долей параллелизма — фактически при текущих ограничениях любые длительные операции (обращение к БД, вычисления, веб реквесты), которые занимают какое то реальное, ощутимое время, транслировать невозможно. А это действительно минус, увы.

1. List всё-таки совсем не замена yield, так как возвращает данные по мере поступления (вычисления или получения из сетевого соединения) и специально создан для тех случаев, когда коллекция целиком может не влезть в память. Непосредственно ключевое слово yield встречается редко потому, что он обёрнут низкоуровневыми драйверами баз данных и прочим linq, которые возвращают IEnumerable, внутри которых ленивая подгрузка данных.

2. Раз struct безусловно переделывается в класс, означает ли это что default(T) работает некорректно? Это достаточно важно, так как и решарпер, и ms code analysis просит убрать ненужную проверку на null в структурах, так как там в принципе не может быть null, а без правильно работающего default, отсутствие null гарантировать уже сложнее
1. Ну конечно есть случаи yield, которые нельзя смоделировать List- ом, кто же спорит. Но их обычно не много, и неужели ради нескольких таких мест стоит отказываться от предлагаемой возможности?
2. default(T) для структур в Java преобразуется в new T(). Он во основном нормально работает, но если где то встретилось a = b для структуры, а потом поменялись поля b, то у а они тоже поменяются, так как для классов это один объект. Если таких ситуаций нет или делать a = new(b) (кстати, вроде UniSharping такие ситуации пытается отслеживать вызывать new, я уже не помню — отказался от структур), то всё будет работать.
Это называется не «ньюансы при присваиваниях», а «структуры не работают». Конвертер должен либо вставлять операцию клонирования самостоятельно, либо выдавать ошибку.

Можно взять Bridge.NET, скомпилировать C# в JavaScript, а уже его заэмбеддить в Java/Python. Есть большое подозрение, что процесс будет менее болезненным, чем применение представленного транслятора. Ибо у Bridge.NET полная поддержка самого C#, включая семантику структур, а портированный на JS набор класс BCL достаточно богатый, да и рефлексия работает целиком (хоть и увеличивает размер бандла, если её включить).

Ограничений U# в конструкциях языка оказалось немного – это атавизмы goto и case goto, а также yield, не моделируемый адекватно в автоматическом режиме.

async/await, похоже, тоже не поддерживается.
А вот это уже критично.
Скажете — поддержим. Важно, чтобы «интерес был не праздным». Если есть реальная потребность такого перевода, то можем обсудить доработки. А если просто так, то да, пока не поддерживается.
У меня интереса никакого к этому проекту нет.
Просто, кажется, что async/await — это одна из самых важных фич в C# на данный момент.
В Python, кстати, она тоже есть.
Спасибо за комментарий, конечно, в ближайшее время поддержим (а для Java смоделируем). Я уже даже выложил 1.2, где async\await корректно обрабатываются. Фича очень важная, просто мне пока не была нужна, поэтому и оказалась нереализованной. Она не входит в множество принципиальных ограничений U# (как goto или unsafe), просто руки не до всего ещё дошли.

Проще работать с байткодом CLR, чем с исходниками.
async/await и прочие новые возможности языка являются сахаром и в MSIL не существует.


Бонусом пойдет поддержка других .NET языков

Ну может. Поддержать J# — это круто! Интересно, сколько человек в мире его использует, хотя бы 1K наберётся?
Речь ведь не только и не столько о J#, сколько о VB.NET и F#
Да, пожалуй. Хотя подозреваю, что по сравнению с C# программистов на других шарпах сильно меньше. Это можно оценить по количеству книг в крупных магазинах, посвящённых тому или иному языку. На F# я не встречал ни одной, по VB# может одна, а остальные 10-15 по C#. По крайней мере, так было год назад. Поддержать VB# в UniSharping — вопрос пары дней, если будет проект, то обсудим.
VB.NET ну очень распространён. Его преподают в старших классах и государственный с муниципальным сектором используют его достаточно широко (много вакансий).

Типичная, кстати, задача — перевод старого проекта c VB6 на VB.NET
Какая разница?
Главное чтобы в итоге из кода на C# получался адекватный код на других яызках.
И AST как раз в этом плане работать гораздо проще чем с MSIL.
В сторону Haxe не смотрели?
Одно из условий задачи — на входе проект C#
Ну так можно написать один конвертер из C# в Haxe, не?
Хорошая мысля приходит опосля… Да, буду иметь в виду, спасибо, поддержать Haxe!
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Ну разумеется, у меня пока идеи исчерпались, ждём нормального проекта и предложений, чтобы продвинуться дальше. Идея с хинтами (комментариями своего формата) вместе с директивами препроцессора — очень мощный инструмент для этой задачи.
Так и я об этом же! Можно писать на C#, а получать код на нужном языке. Но только конвертер нужен не «в C#», а «из C#». Так как у ряда заказчиков требование СПО — критичное (см. конец статьи).
НЛО прилетело и опубликовало эту надпись здесь
Усилия потребуются, но на стороне C#. А вот на приёмной стороне усилий не требуется никаких, поскольку генерируется сразу рабочий вариант. Когда я делаю очередной релиз Pullenti, то SDK на Java и Python получаются автоматом и не требуют никакого ручного участия (и сразу отгружаются скриптом на сайт). Мои коллеги по 3-м проектам на Java не дадут соврать…
НЛО прилетело и опубликовало эту надпись здесь
Такая возможность есть — можно игнорировать указанные namespace, а также использовать #if… #endif для отключения ненужных фрагментов. Раньше даже были поддержаны хинты типа //JAVA ignored для любых конструкций языка, но потом я это обрал — достаточно директив препроцессора.
> Ограничений U# в конструкциях языка оказалось немного – это
> атавизмы goto и case goto,
Конечные автоматы — бай-бай.

> а также yield, не моделируемый адекватно в автоматическом режиме.
Грусть-печаль… Работа с коллекциями, до скорых встреч.

> Не рекомендуется (хотя и можно) использовать struct,
Прощай быстродействие.
Да, бедные Java и Python — они лишены всего этого богатства…
А как же генераторы в Питоне?
А генераторы в Питоне есть — там всё через генераторы (если имеется в виду generic). Любой метод def f(x, y) уже на генераторах — аналог void f<X, Y>(X x, Y y). Так что здесь конвертация C#->Python просто игнорирует генераторы C#, и всё работает. Но возникают другие проблемы (с одинаковыми именами) — всё это описано в документации.
Ого, не знал про такое в Python! На него я настраивался уже после Java, и не обратил внимание. Значит, yield для Python вполне возможен, и одним ограничением U# меньше, спасибо! А не найдётся ли что-нибудь для goto? ;)
Аналогов goto, к сожалению, в Python нет =(
Говорят, полезно погрузиться в область ;)
НЛО прилетело и опубликовало эту надпись здесь
Вообще говоря, посыл, задаваемый как цель конверсии немного странный.

Если цель получить в результате конверсии СПО, то миграция с языка C# (с лицензией MIT) на Python (имеющий более ограниченный по сравнению с MIT лицензию BSD) или на Java (вирусная GPL или проприеритарная JCP) выглядит довольно непоследовательно.

А что ещё более непоследовательно, так это использовать проприетарный тул для этого с закрытыми исходниками и с непонятной лицензией.
А в чём глубинный смысл невыкладывания на GitHub исходного кода, при том, что:
система бесплатна для некоммерческого использования
?
Глубинный смысл в том, что она платна для коммерческого использования. Я без пропитания пока не могу… Хотя проект этот и второстепенный, но труда в него вложено немало. Жалко вот так вот сразу. Может, со временем и выложу.
Вы для себя определитесь — или крестик или штаны. Для бесплатного использования в сообществе принято пользоваться открытыми продуктами. Это в общем-то даже важнее чем бесплатность. Для некоммерческого использования, разумеется.
Хорошо, если Вы не пользуетесь бесплатными продуктами без исходных кодов, то это пожалуйста. Значит, пока UniShapring Вам не подойдёт. Как и всем тем, кто не пишет на C# (он просто не нужен). Или тем, кто разрабатывает мощные GUI-приложения на C# (конвертация малореальна). Как и тем, заказчики кого удовлетворяются .NET. И т.д.
Речь здесь не столько обо мне, сколько о вас. Вы не доверяете мне и боитесь что я буду использовать вашу интеллектуальную собственность в коммерческих целях. Имеете полное право. Но почему я должен доверять вам по поводу отсутствия закладок в закрытом коде? И что еще важнее. Понадобилось что-то чуть доработать. Да, можно поискать вас, заплатить денег и вы сделаете. Не вопрос. Но что если вас найти не удастся? Таким образом, ценность бесплатного инструмента без открытых исходников стремительно падает. Я понятно объясняю?
После столь развернутого объяснения стало чуть понятнее, спасибо.
Интересно, Вы в ресторане, скажем, просите официанта принести исходный продукт для его потребления? А то вдруг повар там что от себя лишнего добавит, а так всегда можно самому скомпилировать блюдо, или вдруг повар пропадёт и не сможет внести изменение, ищи его потом свищи… А автомобиль — с описанием технологии, вдруг потребуется что-нибудь исправить.
Непродуманные аналогии опасны. Ваша позиция ясна. Дальнейшая дискуссия бессмысленна.
Стыдно)
Странная реакция… Кстати, а Вы сами чем-нибудь поделились с народом на том же GitHub?
Сначала добейся, да? (:
У меня в профиле есть ссылка на GitHub профиль. Можете сами посмотреть.
Да, посмотрел, круто! Какому можно бросить камень упрёка, принимается.
Это была невинная шутка, а не упрёк)
Прошу прощения, это я промазал.
Вы сами чем-нибудь поделились с народом на том же GitHub

Это пойдёт?
Впечатляет, снимаю шляпу!
> Вы для себя определитесь — или крестик или штаны
Крестик и штаны пока оставлю.
Ваше право. Вы отпугиваете потенциальных пользователей (не меня), только и всего.

А сам UniSharping написан на C#? Может ли его исходный код быть конвертирован в Java или Python?

Да, может, и это один из тестов корректности
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории