Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 3424|回复: 5
打印 上一主题 下一主题

scheme.tl Understanding the Type Language

[复制链接]

1272

主题

2067

帖子

7958

积分

认证用户组

Rank: 5Rank: 5

积分
7958
跳转到指定楼层
楼主
发表于 2020-2-27 11:22:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
https://docs.telethon.dev/en/lat ... -type-language.html
Understanding the Type Language¶

Telegram’s Type Language(also known as TL, found on .tl files) is a concise way to definewhat other programming languages commonly call classes or structs.

Every definition is written as follows for a Telegram object is definedas follows:

name#id argument_name:argument_type = CommonType

This means that in a single line you know what the TLObject name is.You know it’s unique ID, and you know what arguments it has. It reallyisn’t that hard to write a generator for generating code to anyplatform!

The generated code should also be able to encode the TLObject (letthis be a request or a type) into bytes, so they can be sent over thenetwork. This isn’t a big deal either, because you know how theTLObject’s are made, and how the types should be serialized.

You can either write your own code generator, or use the one thislibrary provides, but please be kind and keep some special mention tothis project for helping you out.

This is only a introduction. The TL language is not that easy. Butit’s not that hard either. You’re free to sniff thetelethon_generator/ files and learn how to parse other more complexlines, such as flags (to indicate things that may or may not bewritten at all) and vector’s.




回复

使用道具 举报

1272

主题

2067

帖子

7958

积分

认证用户组

Rank: 5Rank: 5

积分
7958
沙发
 楼主| 发表于 2020-2-27 11:33:04 | 只看该作者
回复 支持 反对

使用道具 举报

1272

主题

2067

帖子

7958

积分

认证用户组

Rank: 5Rank: 5

积分
7958
板凳
 楼主| 发表于 2020-2-27 14:52:57 | 只看该作者
本帖最后由 Qter 于 2020-2-27 15:47 编辑

1>------ 已启动全部重新生成: 项目: lib_scheme, 配置: Debug Win32 ------
1>Cleaning... 0 files.
1>ninja: Entering directory `..\out\Debug\'
1>[1/4] ACTION codegen_scheme-ing scheme.tl..
1>EXEC : warning : counted 505bce7 mismatch with provided 3b9acde9 (auth.kefuLogin#3b9acde9, auth.kefuLogin kefu_login_name:string kefu_login_password:string auth_code:string = auth.Authorization)
1>
1>[2/4] STAMP obj\lib_scheme.actions_rules_copies.stamp
1>[3/4] CXX obj\gen\lib_scheme.scheme.obj
1>注意: 包含文件:  D:\TBuild\longchat-tdesktop\out\Debug\gen\scheme.h



codegen_scheme.py 里对key值生成方法进行了验证
countTypeId = binascii.crc32(binascii.a2b_qp(cleanline));
if (typeid != countTypeId):
print('Warning: counted ' + countTypeId + ' mismatch with provided ' + typeid + ' (' + key + ', ' + cleanline + ')' + '-->' +countTypeId);

回复 支持 反对

使用道具 举报

1272

主题

2067

帖子

7958

积分

认证用户组

Rank: 5Rank: 5

积分
7958
地板
 楼主| 发表于 2020-3-2 11:52:50 | 只看该作者
本帖最后由 Qter 于 2020-3-2 11:58 编辑

scheme.tl中的定义
  1. messages.sendMessage#fa88427a flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
复制代码
自动生成的代码
scheme.h
  1. class MTPmessages_sendMessage { // RPC method 'messages.sendMessage'
  2. public:
  3.         enum class Flag : uint32 {
  4.                 f_no_webpage = (1U << 1),
  5.                 f_silent = (1U << 5),
  6.                 f_background = (1U << 6),
  7.                 f_clear_draft = (1U << 7),
  8.                 f_reply_to_msg_id = (1U << 0),
  9.                 f_reply_markup = (1U << 2),
  10.                 f_entities = (1U << 3),

  11.                 MAX_FIELD = (1U << 7),
  12.         };
  13.         using Flags = base::flags<Flag>;
  14.         friend inline constexpr auto is_flag_type(Flag) { return true; };

  15.         bool is_no_webpage() const { return vflags.v & Flag::f_no_webpage; }
  16.         bool is_silent() const { return vflags.v & Flag::f_silent; }
  17.         bool is_background() const { return vflags.v & Flag::f_background; }
  18.         bool is_clear_draft() const { return vflags.v & Flag::f_clear_draft; }
  19.         bool has_reply_to_msg_id() const { return vflags.v & Flag::f_reply_to_msg_id; }
  20.         bool has_reply_markup() const { return vflags.v & Flag::f_reply_markup; }
  21.         bool has_entities() const { return vflags.v & Flag::f_entities; }

  22.         MTPflags<MTPmessages_sendMessage::Flags> vflags;
  23.         MTPInputPeer vpeer;
  24.         MTPint vreply_to_msg_id;
  25.         MTPstring vmessage;
  26.         MTPlong vrandom_id;
  27.         MTPReplyMarkup vreply_markup;
  28.         MTPVector<MTPMessageEntity> ventities;

  29.         MTPmessages_sendMessage() = default;
  30.         MTPmessages_sendMessage(const MTPflags<MTPmessages_sendMessage::Flags> &_flags, const MTPInputPeer &_peer, MTPint _reply_to_msg_id, const MTPstring &_message, const MTPlong &_random_id, const MTPReplyMarkup &_reply_markup, const MTPVector<MTPMessageEntity> &_entities) : vflags(_flags), vpeer(_peer), vreply_to_msg_id(_reply_to_msg_id), vmessage(_message), vrandom_id(_random_id), vreply_markup(_reply_markup), ventities(_entities) {
  31.         }

  32.         uint32 innerLength() const;
  33.         mtpTypeId type() const {
  34.                 return mtpc_messages_sendMessage;
  35.         }
  36.         void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_sendMessage);
  37.         void write(mtpBuffer &to) const;

  38.         using ResponseType = MTPUpdates;
  39. };
  40. using MTPmessages_SendMessage = MTPBoxed<MTPmessages_sendMessage>;
复制代码
scheme.cpp

  1. uint32 MTPmessages_sendMessage::innerLength() const {
  2.         return vflags.innerLength() + vpeer.innerLength() + (has_reply_to_msg_id() ? vreply_to_msg_id.innerLength() : 0) + vmessage.innerLength() + vrandom_id.innerLength() + (has_reply_markup() ? vreply_markup.innerLength() : 0) + (has_entities() ? ventities.innerLength() : 0);
  3. }
  4. void MTPmessages_sendMessage::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
  5.         vflags.read(from, end);
  6.         vpeer.read(from, end);
  7.         if (has_reply_to_msg_id()) { vreply_to_msg_id.read(from, end); } else { vreply_to_msg_id = MTPint(); }
  8.         vmessage.read(from, end);
  9.         vrandom_id.read(from, end);
  10.         if (has_reply_markup()) { vreply_markup.read(from, end); } else { vreply_markup = MTPReplyMarkup(); }
  11.         if (has_entities()) { ventities.read(from, end); } else { ventities = MTPVector<MTPMessageEntity>(); }
  12. }
  13. void MTPmessages_sendMessage::write(mtpBuffer &to) const {
  14.         vflags.write(to);
  15.         vpeer.write(to);
  16.         if (has_reply_to_msg_id()) vreply_to_msg_id.write(to);
  17.         vmessage.write(to);
  18.         vrandom_id.write(to);
  19.         if (has_reply_markup()) vreply_markup.write(to);
  20.         if (has_entities()) ventities.write(to);
  21. }
复制代码
代码中的调用
  1. auto sendFlags = MTPmessages_SendMessage::Flags(0);
  2.         sendFlags |= MTPmessages_SendMessage::Flag::f_reply_to_msg_id;
  3. sendFlags |= MTPmessages_SendMessage::Flag::f_no_webpage;
  4. sendFlags |= MTPmessages_SendMessage::Flag::f_silent;
  5. lastMessage = history->addNewMessage(
  6.                         MTP_message(
  7.                                 MTP_flags(flags),
  8.                                 MTP_int(newId.msg),
  9.                                 MTP_int(messageFromId),
  10.                                 peerToMTP(peer->id),
  11.                                 MTPMessageFwdHeader(),
  12.                                 MTPint(),
  13.                                 MTP_int(message.replyTo),
  14.                                 MTP_int(unixtime()),
  15.                                 msgText,
  16.                                 media,
  17.                                 MTPReplyMarkup(),
  18.                                 localEntities,
  19.                                 MTP_int(1),
  20.                                 MTPint(),
  21.                                 MTP_string(messagePostAuthor),
  22.                                 MTPlong()),
  23.                         NewMessageUnread);
  24.                 history->sendRequestId = request(MTPmessages_SendMessage(
  25.                         MTP_flags(sendFlags),
  26.                         peer->input,
  27.                         MTP_int(message.replyTo),
  28.                         msgText,
  29.                         MTP_long(randomId),
  30.                         MTPReplyMarkup(),
  31.                         sentEntities
  32.                 )).done([=](const MTPUpdates &result) {
  33.                         applyUpdates(result, randomId);
  34.                         history->clearSentDraftText(QString());
  35.                 }).fail([=](const RPCError &error) {
  36.                         if (error.type() == qstr("MESSAGE_EMPTY")) {
  37.                                 lastMessage->destroy();
  38.                         } else {
  39.                                 sendMessageFail(error);
  40.                         }
  41.                         history->clearSentDraftText(QString());
  42.                 }).afterRequest(history->sendRequestId
  43.                 ).send();
复制代码
日志:
发送
  1. [11:56:21.034 01-0006421] (dc:2) Send: { core_message
  2.   msg_id: 6799454597686760760 [LONG],
  3.   seq_no: 352 [INT],
  4.   bytes: 148 [INT],
  5.   body: { msg_container
  6.     messages: [ vector<0xffffffffffffffff>
  7.       { core_message
  8.         msg_id: 6799454597686728540 [LONG],
  9.         seq_no: 351 [INT],
  10.         bytes: 88 [INT],
  11.         body: { messages_sendMessage
  12.           flags: 128 [INT],
  13.           no_webpage: [ SKIPPED BY BIT 1 IN FIELD flags ],
  14.           silent: [ SKIPPED BY BIT 5 IN FIELD flags ],
  15.           background: [ SKIPPED BY BIT 6 IN FIELD flags ],
  16.           clear_draft: YES [ BY BIT 7 IN FIELD flags ],
  17.           peer: { inputPeerChat
  18.             chat_id: 1 [INT],
  19.           },
  20.           reply_to_msg_id: [ SKIPPED BY BIT 0 IN FIELD flags ],
  21.           message: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" [STRING],
  22.           random_id: 14114719467741365869 [LONG],
  23.           reply_markup: [ SKIPPED BY BIT 2 IN FIELD flags ],
  24.           entities: [ SKIPPED BY BIT 3 IN FIELD flags ],
  25.         },
  26.       },
  27.       { core_message
  28.         msg_id: 6799454597686745724 [LONG],
  29.         seq_no: 352 [INT],
  30.         bytes: 20 [INT],
  31.         body: { msgs_ack
  32.           msg_ids: [ vector<0x22076cba>
  33.             6799454563309987337 [LONG],
  34.           ],
  35.         },
  36.       },
  37.     ],
  38.   },
  39. }
复制代码
返回

  1. [11:56:21.247 01-0006436] (dc:2) Recv: { core_message
  2.   msg_id: 6799454593288775185 [LONG],
  3.   seq_no: 51 [INT],
  4.   bytes: 292 [INT],
  5.   body: { rpc_result
  6.     req_msg_id: 6799454597686728540 [LONG],
  7.     result: { updates
  8.       updates: [ vector<0x0>
  9.         { updateMessageID
  10.           id: 172 [INT],
  11.           random_id: 14114719467741365869 [LONG],
  12.         },
  13.         { updateNewMessage
  14.           message: { message
  15.             flags: 770 [INT],
  16.             out: YES [ BY BIT 1 IN FIELD flags ],
  17.             mentioned: [ SKIPPED BY BIT 4 IN FIELD flags ],
  18.             media_unread: [ SKIPPED BY BIT 5 IN FIELD flags ],
  19.             silent: [ SKIPPED BY BIT 13 IN FIELD flags ],
  20.             post: [ SKIPPED BY BIT 14 IN FIELD flags ],
  21.             from_scheduled: [ SKIPPED BY BIT 18 IN FIELD flags ],
  22.             id: 172 [INT],
  23.             from_id: 10000001 [INT],
  24.             to_id: { peerChat
  25.               chat_id: 1 [INT],
  26.             },
  27.             fwd_from: [ SKIPPED BY BIT 2 IN FIELD flags ],
  28.             via_bot_id: [ SKIPPED BY BIT 11 IN FIELD flags ],
  29.             reply_to_msg_id: [ SKIPPED BY BIT 3 IN FIELD flags ],
  30.             date: 1583121389 [INT],
  31.             message: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" [STRING],
  32.             media: { messageMediaEmpty },
  33.             reply_markup: [ SKIPPED BY BIT 6 IN FIELD flags ],
  34.             entities: [ SKIPPED BY BIT 7 IN FIELD flags ],
  35.             views: [ SKIPPED BY BIT 10 IN FIELD flags ],
  36.             edit_date: [ SKIPPED BY BIT 15 IN FIELD flags ],
  37.             post_author: [ SKIPPED BY BIT 16 IN FIELD flags ],
  38.             grouped_id: [ SKIPPED BY BIT 17 IN FIELD flags ],
  39.           },
  40.           pts: 316 [INT],
  41.           pts_count: 1 [INT],
  42.         },
  43.       ],
  44.       users: [ vector<0x0>
  45.         { user
  46.           flags: 4201591 [INT],
  47.           self: YES [ BY BIT 10 IN FIELD flags ],
  48.           contact: YES [ BY BIT 11 IN FIELD flags ],
  49.           mutual_contact: YES [ BY BIT 12 IN FIELD flags ],
  50.           deleted: [ SKIPPED BY BIT 13 IN FIELD flags ],
  51.           bot: [ SKIPPED BY BIT 14 IN FIELD flags ],
  52.           bot_chat_history: [ SKIPPED BY BIT 15 IN FIELD flags ],
  53.           bot_nochats: [ SKIPPED BY BIT 16 IN FIELD flags ],
  54.           verified: [ SKIPPED BY BIT 17 IN FIELD flags ],
  55.           restricted: [ SKIPPED BY BIT 18 IN FIELD flags ],
  56.           min: [ SKIPPED BY BIT 20 IN FIELD flags ],
  57.           bot_inline_geo: [ SKIPPED BY BIT 21 IN FIELD flags ],
  58.           support: [ SKIPPED BY BIT 23 IN FIELD flags ],
  59.           id: 10000001 [INT],
  60.           access_hash: 1827705845932265805 [LONG],
  61.           first_name: "13812345678" [STRING],
  62.           last_name: "t" [STRING],
  63.           username: [ SKIPPED BY BIT 3 IN FIELD flags ],
  64.           phone: "8613812345678" [STRING],
  65.           photo: { userProfilePhotoEmpty },
  66.           status: { userStatusOnline
  67.             expires: 1583121449 [INT],
  68.           },
  69.           bot_info_version: [ SKIPPED BY BIT 14 IN FIELD flags ],
  70.           restriction_reason: [ SKIPPED BY BIT 18 IN FIELD flags ],
  71.           bot_inline_placeholder: [ SKIPPED BY BIT 19 IN FIELD flags ],
  72.           lang_code: "" [STRING],
  73.         },
  74.       ],
  75.       chats: [ vector<0x0>
  76.         { chat
  77.           flags: 262144 [INT],
  78.           creator: [ SKIPPED BY BIT 0 IN FIELD flags ],
  79.           kicked: [ SKIPPED BY BIT 1 IN FIELD flags ],
  80.           left: [ SKIPPED BY BIT 2 IN FIELD flags ],
  81.           deactivated: [ SKIPPED BY BIT 5 IN FIELD flags ],
  82.           id: 1 [INT],
  83.           title: "tangtest" [STRING],
  84.           photo: { chatPhotoEmpty },
  85.           participants_count: 1 [INT],
  86.           date: 1578387290 [INT],
  87.           version: 1 [INT],
  88.           migrated_to: [ SKIPPED BY BIT 6 IN FIELD flags ],
  89.           admin_rights: [ SKIPPED BY BIT 14 IN FIELD flags ],
  90.           default_banned_rights: { chatBannedRights
  91.             flags: 0 [INT],
  92.             view_messages: [ SKIPPED BY BIT 0 IN FIELD flags ],
  93.             send_messages: [ SKIPPED BY BIT 1 IN FIELD flags ],
  94.             send_media: [ SKIPPED BY BIT 2 IN FIELD flags ],
  95.             send_stickers: [ SKIPPED BY BIT 3 IN FIELD flags ],
  96.             send_gifs: [ SKIPPED BY BIT 4 IN FIELD flags ],
  97.             send_games: [ SKIPPED BY BIT 5 IN FIELD flags ],
  98.             send_inline: [ SKIPPED BY BIT 6 IN FIELD flags ],
  99.             embed_links: [ SKIPPED BY BIT 7 IN FIELD flags ],
  100.             send_polls: [ SKIPPED BY BIT 8 IN FIELD flags ],
  101.             change_info: [ SKIPPED BY BIT 10 IN FIELD flags ],
  102.             invite_users: [ SKIPPED BY BIT 15 IN FIELD flags ],
  103.             pin_messages: [ SKIPPED BY BIT 17 IN FIELD flags ],
  104.             until_date: 2147483647 [INT],
  105.           },
  106.         },
  107.       ],
  108.       date: 1583121389 [INT],
  109.       seq: 0 [INT],
  110.     },
  111.   },
  112. }
复制代码
回复 支持 反对

使用道具 举报

1272

主题

2067

帖子

7958

积分

认证用户组

Rank: 5Rank: 5

积分
7958
5#
 楼主| 发表于 2020-3-2 14:25:21 | 只看该作者
本帖最后由 Qter 于 2020-3-2 15:11 编辑

kf登录及返回定义

复制代码
生成的结构
  1. MTPauth_Authorization& result
  2. auto& d = result.c_auth_authorization();
  3. QString phone = qs(d.vuser.c_user().vphone);
  4. d.vuser.c_user().is_self()

  5. class MTPauth_authorization : private MTP::internal::TypeDataOwner {
  6. public:
  7.         MTPauth_authorization();
  8.         const MTPDauth_authorization &c_auth_authorization() const;

  9.         ....
  10. };


  11. class MTPDauth_authorization : public MTP::internal::TypeData {
  12. public:
  13.         ...
  14.         MTPUser vuser;
  15. };

  16. class MTPuser : private MTP::internal::TypeDataOwner {
  17. public:
  18.        
  19.         const MTPDuser &c_user() const;

  20.         ...
  21. };
  22. using MTPUser = MTPBoxed<MTPuser>;

  23. class MTPDuser : public MTP::internal::TypeData {
  24. public:
  25.         template <typename Other>
  26.         static constexpr bool Is() { return std::is_same_v<std::decay_t<Other>, MTPDuser>; };

  27.         enum class Flag : uint32 {
  28.                 f_self = (1U << 10),
  29.                 f_contact = (1U << 11),
  30.                 f_mutual_contact = (1U << 12),
  31.                 f_deleted = (1U << 13),
  32.                 f_bot = (1U << 14),
  33.                 f_bot_chat_history = (1U << 15),
  34.                 f_bot_nochats = (1U << 16),
  35.                 f_verified = (1U << 17),
  36.                 f_restricted = (1U << 18),
  37.                 f_min = (1U << 20),
  38.                 f_bot_inline_geo = (1U << 21),
  39.                 f_support = (1U << 23),
  40.                 f_access_hash = (1U << 0),
  41.                 f_first_name = (1U << 1),
  42.                 f_last_name = (1U << 2),
  43.                 f_username = (1U << 3),
  44.                 f_phone = (1U << 4),
  45.                 f_photo = (1U << 5),
  46.                 f_status = (1U << 6),
  47.                 f_bot_info_version = (1U << 14),
  48.                 f_restriction_reason = (1U << 18),
  49.                 f_bot_inline_placeholder = (1U << 19),
  50.                 f_lang_code = (1U << 22),

  51.                 MAX_FIELD = (1U << 23),
  52.         };
  53.         using Flags = base::flags<Flag>;
  54.         friend inline constexpr auto is_flag_type(Flag) { return true; };

  55.         bool is_self() const { return vflags.v & Flag::f_self; }
  56.         bool is_contact() const { return vflags.v & Flag::f_contact; }
  57.         bool is_mutual_contact() const { return vflags.v & Flag::f_mutual_contact; }
  58.         bool is_deleted() const { return vflags.v & Flag::f_deleted; }
  59.         bool is_bot() const { return vflags.v & Flag::f_bot; }
  60.         bool is_bot_chat_history() const { return vflags.v & Flag::f_bot_chat_history; }
  61.         bool is_bot_nochats() const { return vflags.v & Flag::f_bot_nochats; }
  62.         bool is_verified() const { return vflags.v & Flag::f_verified; }
  63.         bool is_restricted() const { return vflags.v & Flag::f_restricted; }
  64.         bool is_min() const { return vflags.v & Flag::f_min; }
  65.         bool is_bot_inline_geo() const { return vflags.v & Flag::f_bot_inline_geo; }
  66.         bool is_support() const { return vflags.v & Flag::f_support; }
  67.         bool has_access_hash() const { return vflags.v & Flag::f_access_hash; }
  68.         bool has_first_name() const { return vflags.v & Flag::f_first_name; }
  69.         bool has_last_name() const { return vflags.v & Flag::f_last_name; }
  70.         bool has_username() const { return vflags.v & Flag::f_username; }
  71.         bool has_phone() const { return vflags.v & Flag::f_phone; }
  72.         bool has_photo() const { return vflags.v & Flag::f_photo; }
  73.         bool has_status() const { return vflags.v & Flag::f_status; }
  74.         bool has_bot_info_version() const { return vflags.v & Flag::f_bot_info_version; }
  75.         bool has_restriction_reason() const { return vflags.v & Flag::f_restriction_reason; }
  76.         bool has_bot_inline_placeholder() const { return vflags.v & Flag::f_bot_inline_placeholder; }
  77.         bool has_lang_code() const { return vflags.v & Flag::f_lang_code; }

  78.         MTPDuser() = default;
  79.         MTPDuser(const MTPflags<MTPDuser::Flags> &_flags, MTPint _id, const MTPlong &_access_hash, const MTPstring &_first_name, const MTPstring &_last_name, const MTPstring &_username, const MTPstring &_phone, const MTPUserProfilePhoto &_photo, const MTPUserStatus &_status, MTPint _bot_info_version, const MTPstring &_restriction_reason, const MTPstring &_bot_inline_placeholder, const MTPstring &_lang_code);

  80.         MTPflags<MTPDuser::Flags> vflags;
  81.         MTPint vid;
  82.         MTPlong vaccess_hash;
  83.         MTPstring vfirst_name;
  84.         MTPstring vlast_name;
  85.         MTPstring vusername;
  86.         MTPstring vphone;
  87.         MTPUserProfilePhoto vphoto;
  88.         MTPUserStatus vstatus;
  89.         MTPint vbot_info_version;
  90.         MTPstring vrestriction_reason;
  91.         MTPstring vbot_inline_placeholder;
  92.         MTPstring vlang_code;
  93. };
复制代码
回复 支持 反对

使用道具 举报

1272

主题

2067

帖子

7958

积分

认证用户组

Rank: 5Rank: 5

积分
7958
6#
 楼主| 发表于 2020-3-3 11:04:37 | 只看该作者
scheme.tl
  1. invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
复制代码
! modifier
In TL, the idempotent operator ! can modify any type, actually making surface values be allowed when its constant values are serialized. However, if T is a standard function like S1->..->Sr->Type, then !T is defined using the equation (!T) a1 ... ar = !(T a1 ... ar), for any a1:S1, ..., ar:Sr.
The ! operator is only allowed in a definition of the types of fields of functional combinators. It is usually used as a type prefix, for example:
set_timeout {X:Type} timeout:int f:!X = X;
In this case, the set_timeout “wrapper” is defined. It takes two explicit parameters: the integer timeout and a surface expression of type X. X : Type is itself an implicit parameter (it is not explicitly stated, rather it is inferred from the values of the other parameters and their types). A similar kind of wrapper may be helpful for modifying the action of RPC queries (which are surface expressions of various types). For example, suppose we have the function
factorial n:int = int;
then we can wrap the RPC query (factorial 100) as follows: (set_timeout 200 (factorial 100)). This expression is still a surface value of type int, which means it can be passed as an RPC query.
A consecutive pair of two computations is another example:
pair {X Y : Type} x:X y:Y = Pair X Y;  // constructorseq_pair {X Y : Type} x:!X y:!Y = Pair X Y; // functional wrapper for sequential computationpar_pair {X Y : Type} x:!X y:!Y = Pair X Y; // functional wrapper for parallel computation
Now the RPC query (seq_pair (factorial 2) (factorial 3)) : Pair int int first calculates factorial 2, then factorial 3, and returns the pair (pair 2 6). In this case, the sequence of operations isn’t important, because they do not have side effects. It would have been just as well to use (par_pair (factorial 2) (factorial 3)). However, this is not always the case.
We can also define an analogy to a “comma” operation:
comma {X Y : Type} x:!X y:!Y = Y;
For example, this operation could first calculate x, then forget the result, calculate y, and return y.
Note that the semantics of the seq_pair, par_pair and comma wrappers are indeed defined where they are implemented (like the semantics of all other functional combinators), not by their TL declaration.
In principle, polymorphic wrappers like set_timeout can also be applied, for example, to “annotate” a RPC response’s constant values. For example, the server might return a response to a query together with the time it was calculated. However, a value of type !X must be constant, because that is what is expected as the enclosing expression’s value. In other words, set_timeout 239 E is a constant/surface value of type X if and only if E is such itself.


回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|firemail ( 粤ICP备15085507号-1 )

GMT+8, 2024-11-22 22:08 , Processed in 0.066048 second(s), 18 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表